编程之美上的题目,是一道dp的题目,设dp[i][v]表示是否可以找到i个数,使得他们的和为v,是的话,dp[i][v]=1,否则为0。
状态转移方程:dp[i][v]=dp[i-1][v-arr[k]] if(v>=arr[k]&&dp[i-1][v-arr[k]]=1),边界条件是dp[0][0]=1
代码还是参考编程之美上的:
//对于每一个物品
for(int k=1;k<=2*n;k++){
//容量最多是n个,而且必须是逆序,否则会有重复
for(i=min(k,n);i>=1;i--)
//这儿v表示所有可能的容量,正序逆序都行
for(int v=1;v<=Sum/2;v++)
if(v>=arr[k]&&dp[i-1][v-arr[k]])
dp[i][v]=1;
}
最后还需要从Sum/2开始->1遍历,找到第一个dp[n][v]不等于0的数。
扩展问题:如果数组中有负数,怎么办?
这我想起了POJ1015.