vijos1153:猫狗大战

描述

新一年度的猫狗大战通过SC(星际争霸)这款经典的游戏来较量,野猫和飞狗这对冤家为此已经准备好久了,为了使战争更有难度和戏剧性,双方约定只能选择Terran(人族)并且只能造机枪兵。

比赛开始了,很快,野猫已经攒足几队机枪兵,试探性的发动进攻;然而,飞狗的机枪兵个数也已经不少了。野猫和飞狗的兵在飞狗的家门口相遇了,于是,便有一场腥风血雨和阵阵惨叫声。由于是在飞狗的家门口,飞狗的兵补给会很快,野猫看敌不过,决定撤退。这时飞狗的兵力也不足够多,所以没追出来。

由于不允许造医生,机枪兵没办法补血。受伤的兵只好忍了。555-
现在,野猫又攒足了足够的兵力,决定发起第二次进攻。为了使这次进攻给狗狗造成更大的打击,野猫决定把现有的兵分成两部分,从两路进攻。由于有些兵在第一次战斗中受伤了,为了使两部分的兵实力平均些,分的规则是这样的:1)两部分兵的个数最多只能差一个;2)每部分兵的血值总和必须要尽可能接近。现在请你编写一个程序,给定野猫现在有的兵的个数以及每个兵的血格值,求出野猫按上述规则分成两部分后每部分兵的血值总和。

格式

输入格式

第一行为一个整数n(1<=n<=200),表示野猫现在有的机枪兵的个数。以下的n行每行一个整数,表示每个机枪兵的血格(1<=ai<=40)。

输出格式

只有一行,包含两个数,即野猫的每部分兵的血值总和,较小的一个值放在前面,两个数用空格分隔。

样例1

样例输入1[复制]

 
3
35
20
32

样例输出1[复制]

 
35 52

限制

各个测试点1s

♂,布尔型dp,用f[j][k]表示j个数中是否能否达到k,首先需要枚举每一个数,然后注意j需要逆序枚举,而k更不用说了;边界是f[0][0]=1;转移方程是f[j][k]|=f[j-1][k-a[i]];其实原理上是用f[i][j][k]表示前i个数中的j个数能否达到k,但是可以用滚动数组优化,滚动数组实际上就是前面的解可以放弃,在这里i不断改变,需要找的只是j和k,所以前面求得的i的jk情况是可以放弃的,和背包一样,f[m]在不断的更新,而前面的f[i][m]的结果没有必要保存。大概这就是滚动数组吧;回到原题,其实他的状态转移方程和背包问题是相似的,都是开始都是不能的,但是渐渐的从0开始能够使一些改变了,然后就一直改变改变到答案==这大概也能称为一种思想吧;逆序只是为了避免重复。然后就是以后要将背包问题充分的应用起来,而不是记住那么几道某某背包的方程就说我背包问题都会了。

原文地址:https://www.cnblogs.com/20003238wzc--/p/4754782.html