The meaning of problems: the right values of 1,2,3,4,5,6 marble, each with several blocks, 2 parts can put them into equal weights. The total number of marble does not exceed 20,000. (Multiple backpack)
Analysis: judge dp [V / 2] == V / 2 can be, but the process will time out if ordinary practices that make multiple backpack as 01 backpack inefficient, this time to use the binary split optimization, the complexity of change for
Binary split Principle:
Here means a large number 11101111, as long as we have a number 1 on each one, can be represented by the large number is 1248 (1101001000 ..) may be expressed in any number, then any number can go through a binary number into a process, for the convenience of each binary number is only one, this process can be seen as divided into the 13 1,2,4,6 (last 6 easy to handle avoid duplication).
Binary split:
for ( int I = . 1 ; I <= n-; I ++ ) { for ( int J = . 1 ; J <[I] = NUM; J = << . 1 ) // binary each enumeration. // NOTE young age to large split { NUM [I] - = J; // subtracting spun off new_c [TOT ++] = J * C [I]; // synthesis of a large volume of articles new_w [tot] = j W * [I]; // synthesis of a large value of the thing } iF (NUM [I]) // . the remainder of determining whether there // if we have a certain item 13, as clearly split into binary 1,2,4. // we have more than 6 out of part of, so they need another serving. { new_c [tot ++] = num [i] * c [i]; new_w [tot] = num [i] * x [i]; num [i] = 0 ; } }
Code:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 0x3f3f3f3f using namespace std; const int maxn=120012; int n,V; int dp[maxn]; int a[7]; int v[maxn],w[maxn]; int main(){ int kase=1; while(scanf("%d %d %d %d %d %d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])!=EOF){ if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0) break; memset(dp,0,sizeof(dp)); printf("Collection #%d:\n",kase++); V=n=0; for(int i=1;i<=6;i++){ V+=a[i]*i; } if(V&1){ printf("Can't be divided.\n\n"); continue; } else{ int tot=0; for(int i=1;i<=6;i++){ for(int j=1;j<=a[i];j<<=1){ a[i]-=j; // printf("a[i]=%d j=%d\n",a[i],j); w[tot]=j*i; v[tot++]=j*i; } if(a[i]!=0){ v[tot]=a[i]*i; w[tot++]=a[i]*i; } } // printf("tot=%d\n",tot); for(int i=0;i<tot;i++){ for(int j=V/2;j>=w[i];j--){ dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } // for(int i=6;i>=1;i--){ // for(int k=v/2;k>=i;k--){ // for(int j=1;j<=a[i];j++){ // if(k-i*j>=0) // dp[k]=max(dp[k],dp[k-i*j]+i*j); // //// printf("dp[k]=%d\n",dp[k]); // } // } // } if(dp[V/2]==V/2) printf("Can be divided.\n\n"); else printf("Can't be divided.\n\n"); } } return 0; }