首页 > 代码库 > TYVJ1194
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 }
TYVJ1194
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。