zoukankan      html  css  js  c++  java
  • 题解报告:hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)

    Problem Description

    急!灾区的食物依然短缺!
    为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
    请问:你用有限的资金最多能采购多少公斤粮食呢?
    后记:
    人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
    月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
    感谢父母,他们给予我们生命,抚养我们成人;
    感谢老师,他们授给我们知识,教我们做人
    感谢朋友,他们让我们感受到世界的温暖;
    感谢对手,他们令我们不断进取、努力。 
    同样,我们也要感谢痛苦与艰辛带给我们的财富~

    Input

    输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。

    Output

    对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。

    Sample Input

    1
    8 2
    2 100 4
    4 100 2

    Sample Output

    400
    解题思路:虽然是多重背包,但数据比较小,可以直接当成01背包来做,即将每种大米的每一袋当成每一件不同的物品来看待,那么就多了一重循环,时间复杂度最坏也就2e5级别,暴力即可。
    AC代码一(15ms):
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=105;
     4 int t,n,m,cost[maxn],weight[maxn],num[maxn],dp[maxn];
     5 int main(){
     6     while(cin>>t){
     7         while(t--){
     8             cin>>n>>m;
     9             for(int i=1;i<=m;i++)
    10                 cin>>cost[i]>>weight[i]>>num[i];
    11             memset(dp,0,sizeof(dp));//注意清0
    12             for(int i=1;i<=m;i++){//m种
    13                 for(int j=1;j<=num[i];j++){//每种num[i]件,转化成01背包
    14                     for(int k=n;k>=cost[i];k--)
    15                         dp[k]=max(dp[k],dp[k-cost[i]]+weight[i]);
    16                 }
    17             }
    18             cout<<dp[n]<<endl;
    19         }
    20     }
    21     return 0;
    22 }

    AC代码二(0ms):

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=105;
     4 int t,W,n,value,weight,num,dp[maxn];
     5 void ZeroOnePack(int w,int v){//01背包
     6     for(int j=W;j>=w;--j)
     7         dp[j]=max(dp[j],dp[j-w]+v);
     8 }
     9 void CompletePack(int w,int v){//完全背包
    10     for(int j=w;j<=W;++j)
    11         dp[j]=max(dp[j],dp[j-w]+v);
    12 }
    13 void MultiplePack(int w,int v,int num){//多重背包
    14     if(w*num>=W)CompletePack(w,v);
    15     else{
    16         for(int k=1;k<=num;k<<=1){//二进制划分物品
    17             ZeroOnePack(w*k,v*k);
    18             num-=k;
    19         }
    20         if(num>0)ZeroOnePack(w*num,v*num);
    21     }
    22 }
    23 int main(){
    24     while(~scanf("%d",&t)){
    25         while(t--){
    26             scanf("%d%d",&W,&n);
    27             memset(dp,0,sizeof(dp));
    28             for(int i=1;i<=n;++i){
    29                 scanf("%d%d%d",&weight,&value,&num);
    30                 MultiplePack(weight,value,num);
    31             }
    32             printf("%d
    ",dp[W]);
    33         }
    34     }
    35     return 0;
    36 }

    AC代码三(0ms):单调队列优化

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int t,W,n,weight,value,num,dp[105];
     4 struct node{
     5     int k,v;
     6     node(int x,int y):k(x),v(y){}
     7 };
     8 deque<node> dq;
     9 void SingleDeque(int w,int v,int cnt){
    10     for(int r=0;r<w;++r){//r=j%w
    11         dq.clear();
    12         for(int t=0;t*w+r<=W;++t){//t=j/w
    13             int tmp=dp[t*w+r]-t*v;
    14             while(!dq.empty()&&tmp>=dq.back().v)dq.pop_back();
    15             dq.push_back(node(t,tmp));
    16             while(!dq.empty()&&(t-cnt>dq.front().k))dq.pop_front();
    17             dp[t*w+r]=dq.front().v+t*v;
    18         }
    19     }
    20 }
    21 int main(){
    22     while(~scanf("%d",&t)){
    23         while(t--){
    24             scanf("%d%d",&W,&n);
    25             memset(dp,0,sizeof(dp));
    26             for(int i=1;i<=n;++i){
    27                 scanf("%d%d%d",&weight,&value,&num);
    28                 num=min(num,W/weight);
    29                 SingleDeque(weight,value,num);
    30             }
    31             printf("%d
    ",dp[W]);
    32         }
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    Leetcode Excel Sheet Column Number
    AlgorithmsI PA2: Randomized Queues and Deques Subset
    AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue
    AlgorithmsI PA2: Randomized Queues and Deques Deque
    AlgorithmsI Programming Assignment 1: PercolationStats.java
    hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题
    hdu多校第四场 1007 (hdu6620) Just an Old Puzzle 逆序对
    hdu多校第四场1001 (hdu6614) AND Minimum Spanning Tree 签到
    hdu多校第三场 1007 (hdu6609) Find the answer 线段树
    hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测
  • 原文地址:https://www.cnblogs.com/acgoto/p/9522352.html
Copyright © 2011-2022 走看看