2
这道题是最简单的动态规划。借着这道题总结一下动态规划问题。
01背包问题
有n个物品,每个物品的重量是w[i],价值是v[i],背包最大承重是w;让你计算背包所能装最大价值的物品。
二维数组的思想
for(int =1;i<=n;i++)
{
for(int j=0;j<=w;j++)
{
if(j<w[i])
d[i][j]=d[i-1][j] //就是它的前一个状态。
else
d[i][j]=max(d[i-1][j],d[i-1][j-w[i]]+v[i]);
}
}
当然有很多没有用的也计算上去大大增加空间的复杂度
这个时候就要降维。利用滚动数组覆盖,只存在两个状态。
一维数组
for(int i=1;i<=n;i++)
{
for(int j=w;j>=w[i];j--) //倒着推过去,其实当j=w的时候是前几个状态的最大价值。
{
d[j]=max(d[j],d[j-w[i]]+v[i]);
}
}
下面是这道题的代码:::::::::
int t; scanf("%d",&t); while(t--) { int n,sum=0; int a[1005]; int dp[100005]; memset(dp,0,sizeof(dp)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]), sum=sum+a[i]; int l=sum/2; for(int i=1;i<=n;i++) { for(int j=l;j>=a[i];j--) dp[j]=max(dp[j],dp[j-a[i]]+a[i]); } printf("%d\n",sum-2*dp[l]); }
