HDU-3578-双塔dp

来源:互联网 发布:性冲动 知乎 编辑:程序博客网 时间:2024/06/07 04:51

题目大意:有n个橘子,选一些装到两个袋子里,要求两个袋子里面重量相同,问袋子最大重量是多少;

题目解析:dp[i][j]表示枚举到第i个橘子,两个袋子差值为j的时候的最大重量,注意橘子可以不取,并且如果有个橘子的重量为0答案就有解,状态转移的话很简单;

AC代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=110;const int offset=2000;int n,dp[maxn][offset*2+10],w[maxn];int main(){    int cas,c=1;    scanf("%d",&cas);    while(cas--)    {        int flag=0,ans=0;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%d",&w[i]);            if(w[i]==0)                flag=1;        }        memset(dp,-1,sizeof(dp));        for(int i=1;i<=n;i++)            dp[i][2000]=0;        dp[0][2000]=0;        for(int i=1;i<=n;i++)        {            for(int j=-2000;j<=2000;j++)            {                dp[i][j+offset]=dp[i-1][j+offset];                if(dp[i-1][j+w[i]+offset]!=-1)                dp[i][j+offset]=max(dp[i][j+offset],dp[i-1][j+w[i]+offset]+w[i]);                if(dp[i-1][j-w[i]+offset]!=-1)                dp[i][j+offset]=max(dp[i][j+offset],dp[i-1][j-w[i]+offset]+w[i]);            }        }        printf("Case %d: ",c++);        if(dp[n][2000]!=0)        {            ans=max(ans,dp[n][2000]/2);        }        if(ans==0&&flag==0)            printf("-1\n");        else            printf("%d\n",ans);    }    return 0;}


0 0