想看更多的解题报告: 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,那么结果应该是这样:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1(10,1) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2(5,4) | 0 | 0 | 0 | 0 | 0 | 4 | 4 | 4 | 4 | 4 | 4 |
3(3,3) | 0 | 0 | 0 | 3 | 3 | 4 | 4 | 4 | 7 | 7 | 7 |
如果只有草药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 1000
int 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;
}