zoukankan      html  css  js  c++  java
  • 佩奇采药

    【问题描述】

         佩奇是只天资聪颖的小猪,她的梦想是成为世界上最伟大的医师。为此,她去找她的奶奶—猪小妹大陆上最有威望的医师。猪奶奶为了判断佩奇的资质,给她出了一个难题。猪奶奶把她带到一个到处都是草药的山洞里对她说:“佩奇,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一只聪明的小猪,你应该可以让采到的草药的总价值最大。”
    佩奇当然能够出色地解决这个问题。如果你是佩奇,你能完成这个任务吗?

    【输入文件】
    输入文件medic.in 的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M<= 100),用一个空格隔开,T 代表总共能够用来采药的时间,M 代表山洞里的草药的数目。接下来的M 行每行包括两个在1 到100 之间(包括1 和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

    【输出文件】
    输出文件medic.out 包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。
    【样例输入】
    70 3
    71 100
    69 1
    1 2
    【样例输出】
    3
    【数据规模】
    对于30%的数据,M <= 10;
    对于全部的数据,M <= 100。

    【胡乱分析】

    这到题是一道经典的动归01背包问题。每种物品只有一件,可以考虑放或者是不放

    这里用f[i][j]来表示前i个物品(不一定是所有前i个物品)恰放入一个容量为j的背包中所获得的最大价值。假设第i个物品已经放入背包了,那么此时留给背包中i-1个物品的放置空间就为背包中总容量减去第i个物品占的空间;假设第i个物品没有放入背包,那么i-1个物品还有全部的空间可以用来放置。

    代码如下

    f[i][j] = max(f[i-1][j],f[i-1][j-w[i]]+c[i]);

    对于这道题来说,原理也是相同的,对于一种草药,只有采与不采两种选择,要是采了这颗草药,时间就得用总时间减去采这颗草药用的时间;要是没采这颗草药,采剩下的草药限制的时间仍旧等于总时间,每次操作均要求出最大价值。
    代码如下

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 struct node
     8 {
     9     int shijian,jiazhi;
    10 }caoyao[105];
    11 int main()
    12 {
    13     int t,m,f[105][105];
    14     memset(f,0,sizeof(f));
    15     scanf("%d%d",&t,&m);
    16     for(int i = 1;i <= m;i++)
    17     {
    18         scanf("%d%d",&caoyao[i].shijian,&caoyao[i].jiazhi);
    19     }
    20     for(int i = 1;i <= m;i++)
    21     {
    22         for(int j = t;j>0;j--)
    23         {
    24             if(caoyao[i].shijian <= j) 
    25                 f[i][j] = max(f[i - 1][j],f[i - 1][j - caoyao[i].shijian] + caoyao[i].jiazhi);
    26             else 
    27                 f[i][j] = f[i - 1][j];
    28         }
    29     }
    30     printf("%d",f[m][t]);
    31     return 0;
    32 }

    对于以上的代码,还可以将二维数组优化成一维

    f[j]=max(f[j],f[j - w[i]]+c[i]);

    代码如下

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<cstring>
     6 using namespace std;
     7 struct node
     8 {
     9     int shijian,jiazhi;
    10 }caoyao[105];
    11 int main()
    12 {
    13     int t,m,f[105];
    14     memset(f,0,sizeof(f));
    15     scanf("%d%d",&m,&t);
    16     for(int i = 1;i <= m;i++)
    17     {
    18         scanf("%d%d",&caoyao[i].shijian,&caoyao[i].jiazhi);
    19     }
    20     for(int i = 1;i <= m;i++)
    21        for(int j = t;j >= caoyao[i].shijian;j--)
    22            f[j] = max(f[j],f[j - caoyao[i].shijian] + caoyao[i].jiazhi);
    23     printf("%d",f[t]);
    24     return 0; 
    25 }
  • 相关阅读:
    codeforces 665C C. Simple Strings(乱搞)
    codeforces 665B B. Shopping(水题)
    codeforces 665A A. Buses Between Cities(水题)
    hdu-2647 Reward && hdu-2049产生冠军 &&hdu-3342Legal or Not(拓扑排序)
    codeforces 450B B. Jzzhu and Sequences(矩阵快速幂)
    hdu-5596 GTW likes gt(模拟+优先队列)
    codeforces 664C C. International Olympiad(数学)
    hdu-5003 Osu!(水题)
    hdu-5000 Clone(dp)
    组合数学中的常见定理&组合数的计算&取模
  • 原文地址:https://www.cnblogs.com/peppa/p/8496394.html
Copyright © 2011-2022 走看看