dp之二维背包poj2576

题意:有一群sb要拔河,把这群sb分为两拨,两拨sb数只差不能大于1,输出这两拨人的体重,小的在前面......

思路:把总人数除2,总重量除2,之后你会发现就是个简单的二维背包,有两个限制.....一个是人数,一个是体重,再仔细思考下,发现一定要有这么多人,也就是说一定要有总人数除以2这么多人,那么当第n个人存在,第n-1个人必须存在.........

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[55][23000],a[105];
int main()
{
    int n;
    while(scanf("%d",&n)>0)
    {
        int m=(n+1)/2,sum=0,maxx=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        if(n==1)
        {
            printf("0 %d\n",a[1]);
            continue;
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=sum/2;k>=0;k--)
                {
                    if(j>0&&k-a[i]>=0&&dp[j-1][k-a[i]]&&dp[j][k]<dp[j-1][k-a[i]]+a[i])
                    dp[j][k]=dp[j-1][k-a[i]]+a[i];
                    //printf("%d\n",dp[j][k]-1);
                    if(maxx<dp[j][k])
                    maxx=dp[j][k];
                }
            }
        }
        maxx--;
        //printf("%d\n",maxx);
        int tmp=sum-maxx;
        if(tmp<maxx)
        {
            int h=tmp;
            tmp=maxx;
            maxx=h;
        }
        printf("%d %d\n",maxx,tmp);
    }
    return 0;
} 

 

posted @ 2013-07-29 12:58  紫忆  阅读(545)  评论(0编辑  收藏  举报