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

    http://acm.hdu.edu.cn/showproblem.php?pid=2191

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 17930    Accepted Submission(s): 7555


    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
     

    Author
    lcy
     

    Source
     

    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1114 2602 2159 1171 1059 
     

    Statistic | Submit | Discuss | Note

     建议自己用这种解法:

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 /* 多重背包 二进制拆分
     7  * Time Complexity  大于O(N*V)
     8  * Space Complexity O(N*V)
     9  * 设 V <= 200 N <= 10 ,拆分后 物品总数 < 50
    10  * 每件物品有 log n[i]种状态
    11  */
    12 
    13 int maxV[721];
    14 int weight[1520]; /* 记录拆分后物体重量 */
    15 int value[1520];  /* 记录拆分后物体价值 */
    16 int V, N;
    17 
    18 int main()
    19 {
    20     int _case;
    21     scanf("%d",&_case);
    22     while(_case--){
    23     int i, j;
    24     scanf("%d%d",&V, &N);
    25     int weig, val, num;
    26     int count = 0;
    27 
    28     for(i = 0; i < N; ++i)
    29     {
    30         scanf("%d%d%d",&weig,&val,&num);
    31 
    32         for(j = 1; j <= num; j*=2) // 二进制拆分
    33         {
    34             weight[count] = j * weig;
    35             value[count++] = j * val;
    36             num -= j;
    37         }
    38         if(num > 0)
    39         {
    40             weight[count] = num * weig;
    41             value[count++] = num * val;
    42         }
    43     }
    44 
    45 
    46     memset(maxV,0,sizeof(maxV));
    47     for(i = 0; i < count; ++i)  // 使用01背包
    48     {
    49         for(j = V; j >= weight[i]; --j)
    50         {
    51             int tmp = maxV[j-weight[i]] + value[i];
    52             maxV[j] = maxV[j] > tmp ? maxV[j] : tmp;
    53         }
    54     }
    55     printf("%d
    ",maxV[V]);}
    56 return 0;}
     1 #include<stdio.h>
     2 #include<string.h>
     3 int dp[101];//dp[j]表示钱为j时能买的最大重量
     4 struct Node
     5 {
     6     int p;//价格
     7     int w;//重量
     8     int c;//数量
     9 }s[102];
    10 int main()
    11 {
    12     int t,N,m;
    13        int i,j,k,temp;
    14     scanf("%d",&t);
    15     while(t--)
    16     {
    17         memset(dp,0,sizeof(dp));
    18         scanf("%d%d",&N,&m);
    19         for(i=1;i<=m;i++)
    20             scanf("%d%d%d",&s[i].p,&s[i].w,&s[i].c);
    21         for(j=0;j<s[1].p;j++)
    22             dp[j] = 0;
    23         for(;j<=N;j++)
    24         {
    25             temp = j/s[1].p;
    26             if(temp <= s[1].c)
    27                 dp[j] = temp * s[1].w;
    28             else
    29                 dp[j] = s[1].c * s[1].w;
    30         }
    31 
    32         for(i=2;i<=m;i++)//米的种类
    33         {
    34             for(j=N;j>=s[i].p;j--)//钱的数量
    35             {
    36                 for(k = 0;k<=s[i].c;k++)//米的代数
    37                 {
    38                     temp = k * s[i].p;
    39                     if(temp <= j )
    40                     {
    41                         if(dp[j-temp]+k*s[i].w > dp[j])
    42                             dp[j] = dp[j-temp]+k*s[i].w;
    43                     }
    44                     else
    45                         break;
    46                 }
    47             }
    48         }
    49         printf("%d
    ",dp[N]);
    50     }
    51     return 0;
    52 }

    二进制拆分:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 const int N=110;
     5 using namespace std;
     6 int n,m;
     7 
     8 struct Rice{
     9     int price;
    10     int weight;
    11     int number;
    12 }rice[N];
    13 int dp[N];
    14 //完全背包
    15 void CompletePack(int cost,int weight){
    16     for(int i=cost;i<=n;i++){
    17         dp[i]=max(dp[i],dp[i-cost]+weight);
    18     }
    19 }
    20 //01背包
    21 void ZeroOnePack(int cost,int weight){
    22     for(int i=n;i-cost>=0;i--){
    23         dp[i]=max(dp[i],dp[i-cost]+weight);
    24     }
    25 }
    26 
    27 //多重背包
    28 void MultiplePack(int cost,int weight,int number){
    29     //如果大于等于金额,就按完全背包处理(此时相当于不限定袋数)//我试过,不用完全背包也可以
    30     if(cost*number>=n){
    31         CompletePack(cost,weight);
    32         return ;
    33     }
    34     int k=1;
    35     while(k<number){
    36         ZeroOnePack(k*cost,k*weight);
    37         number-=k;
    38         k*=2;
    39     }
    40     ZeroOnePack(number*cost,number*weight);
    41 }
    42 
    43 int main(){
    44     int _case;
    45     scanf("%d",&_case);
    46     while(_case--){
    47         scanf("%d%d",&n,&m);
    48         memset(dp,0,sizeof(dp));
    49         for(int i=0;i<m;i++){
    50             scanf("%d%d%d",&rice[i].price,&rice[i].weight,&rice[i].number);
    51         }
    52         for(int i=0;i<m;i++){
    53             MultiplePack(rice[i].price,rice[i].weight,rice[i].number);
    54         }
    55         printf("%d
    ",dp[n]);
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/4539859.html
Copyright © 2011-2022 走看看