zoukankan      html  css  js  c++  java
  • hdu 2844(二进制+多重背包)

    题意:有一些货币告诉你每种的数量与币值。让你算在m内能组合成的的数值个数。

    思路:数据量比较大,用多重背包的做法是会超时的,所以我们需要用二进制优化,记得以前听过这种写法,但是没有写过。今天终于做到这种题了第一次写参考了http://blog.csdn.net/hellobabygogo3/article/details/8013350 主要思路就是用二进制能组成所有v[i]以下的数。

    代码如下:

     1 /**************************************************
     2  * Author     : xiaohao Z
     3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
     4  * Last modified : 2014-04-02 22:58
     5  * Filename     : hdu_2844.cpp
     6  * Description     : 
     7  * ************************************************/
     8 
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <cmath>
    14 #include <algorithm>
    15 #include <queue>
    16 #include <stack>
    17 #include <vector>
    18 #include <set>
    19 #include <map>
    20 #define MP(a, b) make_pair(a, b)
    21 #define PB(a) push_back(a)
    22 
    23 using namespace std;
    24 typedef long long ll;
    25 typedef pair<int, int> pii;
    26 typedef pair<unsigned int,unsigned int> puu;
    27 typedef pair<int, double> pid;
    28 typedef pair<ll, int> pli;
    29 typedef pair<int, ll> pil;
    30 
    31 const int INF = 0x3f3f3f3f;
    32 const double eps = 1E-6;
    33 const int LEN = 2001000;
    34 int dp[LEN];
    35 int n, m, a[LEN], c[LEN];
    36 
    37 int main()
    38 {
    39 //    freopen("in.txt", "r", stdin);
    40 
    41     while(cin >> n >> m){
    42         if(!n && !m) break;
    43         memset(dp, 0, sizeof dp);
    44         for(int i=0; i<n; i++) cin >> a[i];
    45         for(int i=0; i<n; i++) cin >> c[i];
    46         dp[0] = 1;
    47         for(int i=0; i<n; i++){
    48             int j, cnt = c[i];
    49             for(j=1; j<=cnt; j<<=1){
    50                 for(int k=m; k>=j*a[i]; k--){
    51                     if(dp[k - j*a[i]]) dp[k] = 1;
    52                 }
    53                 cnt -= j;
    54             }
    55             if(cnt){
    56                 j = cnt;
    57                 for(int k=m; k>=j*a[i]; k--) if(dp[k-j*a[i]])dp[k] = 1;
    58             }
    59         }
    60         int ans = 0;
    61         for(int i=1; i<=m; i++)if(dp[i]) ans ++;
    62         cout << ans << endl;
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    【POJ
    【OpenJ_Bailian
    【Aizu
    【OpenJ_Bailian
    leetcode-746-Min Cost Climbing Stairs(动态规划)
    leetcode-744-Find Smallest Letter Greater Than Target(改进的二分查找)
    leetcode-728-Self Dividing Numbers
    leetcode-717-1-bit and 2-bit Characters
    leetcode-697-Degree of an Array
    leetcode-682-Baseball Game
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3641986.html
Copyright © 2011-2022 走看看