TYVJ1194

多重背包的二进制优化
题目要求是把所有的物品分成两部分,使得两部分价值之和相等
可以先把总的价值之和m求出然后除2,(如果m是奇数,可以直接Can‘t)然后把第i种大理石分成a[i]个独立的物品,价值和费用都为i,然后把这些物品放入容量为m的背包,如果能恰好放满,则说明可以划分。
时间复杂度O(m*n)m最大为60000 n最大为20000,相乘得1.2*e9
显然会超时,需要优化。多重背包一般都需要二进制优化,这东西不想多说了,背包九讲上很详细(背包九讲真的很强大,你值得拥有!~) 完事,再用恰好装满的01背包算一下,如果dp[m]==m就can否则can‘t

背包九讲全部理解了,背包问题以后应该就不会出问题,所以继续吧。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define INF 11111111
 6 using namespace std;
 7
 8 const int maxv = 60005;
 9 const int maxn = 200;
10 int a[7],s[maxn],dp[maxv];
11 int main()
12 {
13     //freopen("in.txt","r",stdin);
14     int m,n;
15     while(1)
16     {
17         int m = 0,cnt = 1;
18         for(int i = 1;i<=6;++i)
19         {
20             cin>>a[i];
21             m = m+a[i]*i;
22
23             int k = 1;
24             while(a[i]>=k)
25             {
26                 s[cnt++] = k*i;
27                 a[i]-=k;
28                 k*=2;
29             }
30             if(a[i])s[cnt++] = a[i]*i;
31
32         }
33         dp[0] = 0;
34         if(!m)return 0;
35         if(m%2){printf("Can‘t\n");continue;}
36         m/=2;
37         for(int i = 1;i<cnt;++i)
38         {
39             dp[i] = -INF;
40             for(int j = m;j>=s[i];--j)
41                 dp[j]=max(dp[j],dp[j-s[i]]+s[i]);
42         }
43         if(dp[m]==m)printf("Can\n");
44         else printf("Can‘t\n");
45     }
46     return 0;
47 }
时间: 2024-10-07 09:34:08

TYVJ1194的相关文章

TYVJ1276

多重背包+二进制优化这是怎么了,连做俩题都是这东西,不多说了,TYVJ1194唯一的特点是当mi等于-1时,就 mi=g/gi;剩下的就是普通的多重背包二进制优化了. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const int maxv = 50005; 7 const int