HDU 2844 Coins

像下面代码直接利用二进制求解多重背包会超时

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <vector>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 int main(){
10     int n,m;
11     while(cin>>n>>m && n && m){
12         vector<int> A(n),C(n);
13         for(int i = 0 ; i < n; i ++ ) cin >> A[i];
14         for(int i = 0 ; i < n; i ++ ) cin >> C[i];
15         vector<int> coin;
16 
17         for(int i = 0; i < n; i ++ ){
18             int tmp = 1;
19             while(C[i] > tmp){
20                 coin.push_back(tmp*A[i]);
21                 C[i] -= tmp;
22                 tmp <<=1;
23             }
24             coin.push_back(C[i]*A[i]);
25         }
26 
27         vector<int> dp(m+1,0);
28         for(int i = 0 ; i < coin.size(); i ++ ){
29             for(int j = m ; j >= coin[i]; j -- ){
30                 dp[j] = max(dp[j],dp[j-coin[i]] + coin[i]);
31             }
32         }
33 
34         int cnt = 0;
35         for(int i = 1; i <= m ; i++)
36             if(dp[i] != dp[i-1]) cnt++;
37         cout<<cnt<<endl;
38     }
39     return 0;
40 }

参考背包九讲,对多重背包进行优化

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <cstring>
 5 
 6 #define MAX 100000
 7 using namespace std;
 8 
 9 int dp[MAX];
10 
11 void CompletePack(int val, int m){
12     for(int j = val; j <= m; j ++ )
13         dp[j] = max(dp[j],dp[j - val]+ val);
14 }
15 
16 void ZeroOnePack(int val, int m){
17     for(int j = m; j >= val; j -- )
18         dp[j] = max(dp[j],dp[j - val]+ val);
19 }
20 
21 void MultiplePack(int val,int num, int m){
22     if(val*num >= m ){          //对于固定的m来说,相当于有无限个硬币,
23         CompletePack(val,m); //完全背包
24         return;
25     }
26     int k = 1;               //利用二进制优化转化为01背包
27     while( k < num){
28         ZeroOnePack(k*val,m);
29         num -= k;
30         k <<= 1;
31     }
32     ZeroOnePack(num*val,m);
33 }
34 
35 int main(){
36     int n,m;
37     while(cin>>n>>m && n && m){
38         vector<int> A(n),C(n);
39         for(int i = 0 ; i < n; i ++ ) cin >> A[i];
40         for(int i = 0 ; i < n; i ++ ) cin >> C[i];
41         //vector<int> dp(m+1,0);
42         memset(dp,0,sizeof(dp));
43         for(int i=0; i < n; i ++ )
44             MultiplePack(A[i],C[i],m);
45         int cnt = 0;
46         for(int i = 1; i <= m ; i++)
47             if(dp[i] == i) cnt++;
48         cout<<cnt<<endl;
49     }
50     return 0;
51 }

 

posted @ 2013-04-09 17:34  OpenSoucre  阅读(177)  评论(0编辑  收藏  举报