HDU1171(背包)

题意:求把总价值分为两个数,使这两个数接近相等,而且这两个数必须由所有设备中的其中几种设备价值构成,并先输出比较大的数,再输出另一个数。

解题思路:DP算法,背包问题,求法是先求出总价值sum,再用dp[]求sum/2最多能放多少价值!即可以求出其中一个数了,另一个就是sum-dp[sum/2]了……
状态:f[j]:表示软件学院取得容量为j时能获得的最大值,j<=sum/2; 状态转移:f[j]=max{f[j], f[j-v[i]]+v[i]}

注意数组的大小(0<n<=50,0<v<=50,0<m<=100)

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 #define MAX 300000
 6 int dp[MAX],v[1000],m[1000];
 7 int main()
 8 {
 9    int i,j,n,k;
10    while(cin>>n&&n>=0)
11    {
12        int sum=0;
13        for(i=0;i<n;i++)
14        {
15            cin>>v[i]>>m[i];
16            sum+=v[i]*m[i];
17        }
18            memset(dp,0,sizeof(dp));
19            for(i=0;i<n;i++)
20                for(j=1;j<=m[i];j++)
21                    for(k=sum/2;k>=v[i]*j;k--)
22                        if(dp[k]<dp[k-v[i]]+v[i])
23                            dp[k]=dp[k-v[i]]+v[i];
24            if(sum-dp[sum/2]>dp[sum/2])
25                cout<<sum-dp[sum/2]<<" "<<dp[sum/2]<<endl;
26            else cout<<dp[sum/2]<<" "<<sum-dp[sum/2]<<endl;
27    }
28   return 0;
29 }

 

posted @ 2012-04-07 08:39  笑巧  阅读(940)  评论(0编辑  收藏  举报