ural 1005 Stone Pile DP
/*
题目:
把石头分成两堆,问最小的重量差值为多少。
分析:
先求和,然后用和的一半转为01背包。转移方程为:
dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+w[i]);
缩小维度后为dp[j] = max(dp[j],dp[j-w[i]]+w[i]);
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int X = 2000010;
int dp[X],w[25],n;
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
while(cin>>n)
{
if(n==1) //输入为1时,直接输出即可
{
scanf("%d",&w[0]);
cout<<w[0]<<endl;
continue;
}
int sum = 0,temp,ans;
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
sum += w[i];
dp[i] = 0;
}
temp = sum>>1; //除二
dp[0] = 0;
for(int i=1;i<=n;i++) //状态转移方程
for(int j=temp;j>=w[i];j--)
dp[j] = max(dp[j-w[i]]+w[i],dp[j]);
for(int i=temp;i>=0;i--)
if(dp[i]!=0) //当不为零时即为所求的一半石子重量
{
ans = dp[i];
break;
}
ans = 2*ans-sum;
ans = max(ans,-ans);
cout<<ans<<endl;
}
return 0;
}