Multiple backpack binary split method

In the multi-resolution backpack direct method, the number of $ c [i] $ object dismantled into $ c [i] $ different objects

This makes a lot more types of objects, making the low efficiency of the algorithm.

The above-described method $ c [i] is split into $ $ c [i] a $ 1, may be arbitrarily selected so expressed between $ $ $ 1 to $ c [i] all numbers, so as to achieve multiple purposes backpack

I thought, from $ 2 ^ 0,2 ^ 1,2 ^ 2, ..., 2 ^ k $ arbitrarily selected to be shown $ 1 $ $ 2 ^ {k + 1} $ all numbers between -1

So there will be a binary split method :

First, find the maximum of $ k $, such that $ \ sum_ {i = 0} ^ {k} 2 ^ i <= c [i] $

Order $ t = \ sum_ {i = 0} ^ {k} 2 ^ i $, easy to know, above $ k + 1 $ the number may be composed of any number between $ 1 and $ T $ $

That $ t + 1 $ to $ c [i] how the number between $ express it?

Order $ p = c [i] -t $, then split a p, can, for the following reasons:

$ C [i] = p + t, c [i] -1 = p + t-1 ... $ and so on

Since the $ 1 to $ $ t $ has been expressed, so this way $ 1 to $ $ c [i] are each an integer of between $ may be expressed

 

Specifically, it is the number of $ c [i] $ object into a $ k + 2 $, their volumes were $ 2 ^ 0 * v [i], 2 ^ 1 * v [i], .. ., 2 ^ k * v [i], p $

 

Code:

Is $ POJ1742Coins $ code, although it will TLE, when it split method called binary pair of board

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define Ri register int
 5 #define il inline
 6 #define mem(a,b) memset(a,b,sizeof(a))
 7 #define go(i,a,b) for(Ri i=a;i<=b;i++)
 8 #define yes(i,a,b) for(Ri i=a;i>=b;i--)
 9 using namespace std;
10 const int N=101,M=100001;
11 int n,m,t,p,ans,a[N],c[N];
12 bool f[M];
13 il void calc(int x)
14 {
15     t=1,p=0;
16     while(t<=x){t+=(t<<1);p++;}
17     t=x-t/3;p--;
18 }
19 int main()
20 {
21     while(scanf("%d%d",&n,&m)&&n)
22     {
23         mem(f,0);ans=0;
24         go(i,1,n)scanf("%d",&a[i]);
25         go(i,1,n)scanf("%d",&c[i]);
26         f[0]=1;
27         go(i,1,n)
28         {
29             calc(c[i]);
30             go(j,0,p)
31             {
32                 int q=1;if(j)q*=2;
33                 yes(k,m,a[i]*q)
34                 f[k]|=f[k-a[i]*q];
35             }
36             yes(k,m,t)f[k]|=f[k-t];
37         }
38         go(i,1,m)if(f[i])ans++;
39         printf("%d\n",ans);
40     }
41     return 0;
42 }
View Code

 

Guess you like

Origin www.cnblogs.com/forward777/p/10993426.html