• 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 }
  • 相关阅读:
    CF110A Nearly Lucky Number
    Max Sum Plus Plus HDU – 1024
    洛谷 p1003 铺地毯
    poj-1226
    Where is the Marble? UVA – 10474
    Read N Characters Given Read4
    Guess Number Higher or Lower && 九章二分法模板
    Intersection of Two Arrays II
    Reverse Vowels of a String
    Meeting Rooms
  • 原文地址:https://www.cnblogs.com/xiongqiangcs/p/3010570.html
Copyright © 2020-2023  润新知