DP入门之采药问题

来源:互联网 发布:替代硕鼠的软件 编辑:程序博客网 时间:2024/06/08 01:39

                                     想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                     转载请注明出处:
http://blog.csdn.net/wangjian8006

采药
              输入第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值。
              关于输出
              输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。
              例子输入
                  70 3
                  71 100
                  69 1
                  1 2
              例子输出
                  3

我们用maxvalue[i][j]表示,在前i个物品中在j分钟的最大值,那么其实对于一个物品,它有取这个物品和不取这个物品两种状态

假设共有m个物品,总时间是t,times[i]表示第i个物品需要多少时间,values[i]表示第i个物品的价值,且从1开始

拿一个例子来分析

10 3

10 1

5 4

3 3

初始化maxvalue全部为0,那么结果应该是这样:

0123456789100000000000001(10,1)000000000012(5,4)000004444443(3,3)00033444777


 

 

如果只有草药1可选,则花掉全部10分钟,最大值是1
如果还有草药2可选,时间也只够在1,2中选其一,采草药2剩余的时间,也不够采草药1,但是选2比较划算,最大值是4
如果还有草药3可选,在第1‾4分钟,只够采草药3,三种草药之和还是3。
第5--7分钟有可采2和3两种选择,显然,采草药2更划算,选择不采3,最大值是4
到了第8分钟,时间够采2,3,
则最大值是两者价值之和7

 

根据上面,当对于i,取i的话,应该是maxvalue[i][j]=maxvalue[i-1][j-times[i]]+value[i]

那么因为取了i,所以在前i-1个药品中的前j-times[i]分钟的最大分钟再加上i的价值,因为选了i,所以前i-1个药品的时间应该要减去times[i]

如果不取i的话,那么maxvalue[i][j]=maxvalue[i-1][j]前j分钟取i个的最大值应该和前j分钟取前i-1的最大值相等


如果要确定maxvalue[i][j]的最大值,那么

maxvalue[i][j] = max(maxvalue[i-1][j],maxvalue[i-1][j-times[i]]+values[i]);

当然,前提条件是j>=times[i],否则就是时间不够,不能采这个药品


代码如下:

#include <iostream>using namespace std;#define MAXM 100#define MAXT 1000int max(int a,int b){return a>b?a:b;}int times[MAXM],values[MAXM],maxvalue[MAXM][MAXT];int main(){int t,m,i,j;while(scanf("%d%d",&t,&m)!=EOF){for(i=1;i<=m;i++)scanf("%d%d",×[i],&values[i]);memset(maxvalue,0,sizeof(maxvalue));for(i=1;i<=m;i++)for(j=0;j<=t;j++)if(j>=times[i])maxvalue[i][j] = max(maxvalue[i-1][j],maxvalue[i-1][j-times[i]]+values[i]);printf("%d\n",maxvalue[m][t]);}return 0;}


 

原创粉丝点击