雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

双塔DP——hdu3578

Posted on 2011-10-19 22:27  huhuuu  阅读(260)  评论(0编辑  收藏  举报
读题发现 每个物品有三种执行方式:
1。放到轻的那边
2。放到重的那边
3。不放
 dp[i][j]表示到第n个物品时,重量差为j时的重量小的一端的重量,不存在则为-1。
View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

int dp[109][2009];
int a[109];

int main()
{
int i,j,t,n,add=0,s,z=0;

scanf("%d",&t);

while(t--)
{
z=0;
s=0;
add++;
printf("Case %d: ",add);
scanf("%d",&n);
memset(dp,-1,sizeof(dp));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s+=a[i];
if(a[i]==0)z++;
}
dp[1][0]=0;
dp[1][a[1]]=0;

for(i=2;i<=n;i++)
{
for(j=0;j<=s;j++)
{
dp[i][j]=dp[i-1][j];

if(j>=a[i]&&dp[i-1][j-a[i]]!=-1)//放到重的一边
dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]);

if(j<a[i]&&dp[i-1][a[i]-j]!=-1)//放到轻的一边
dp[i][j]=max(dp[i][j],dp[i-1][a[i]-j]+a[i]-j);

if(j+a[i]<=s&&dp[i-1][j+a[i]]!=-1)//放到轻的一边
dp[i][j]=max(dp[i][j],dp[i-1][j+a[i]]+a[i]);
}
}

if(dp[n][0]||(dp[n][0]==0&&z>0))
printf("%d\n",dp[n][0]);
else
printf("-1\n");
}

return 0;
}