您的位置:首页 > 其它

XX采药

2014-03-01 13:22 204 查看
// 描述    XX是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师
// 为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子
// ,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,
// 在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,行你应该可以让采到的草药的总价值最大”。
// 如果你是XX,你能完成这个任务吗? 输入格式    多组数据,每两个整数,用空格隔开,第一行有两个整
// 数T(1 <= T <= 1000)和M(1 <= M <= 100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞
// 里的草药的数目。接下来的M行每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时
// 间和这株草药的价值。 输出格式    输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到
// 的草药的最大总价值。

//动态规划
//
//

#include "stdio.h"
#include "iostream"

using namespace std;
int T,M;//总时间,药材总数
int Jia[101];//每棵药材的价值
int Shi[101];//采每棵药材的时间
int c[101][1001];//c[i][t]表示在t时间内采药材获得的最大收益,但要求所采的药材编号不超过i
int max(int a,int b);
int proceed(int i,int t);//返回c[i][t]

int main(int argc, char* argv[])
{
// 	_int64 i=0;
// 	scanf("%I64d",&i);
// 	printf("%d\n",sizeof(i));
// 	printf("%I64d",i);

//读入数据
while(cin>>T>>M){
memset(c,-1,sizeof(c));
for (int i=1;i<=M;i++)
{
cin>>Shi[i]>>Jia[i];
}
int result=proceed(M,T);
cout<<result<<endl;
}

return 0;
}
//自顶向下
//每棵药材有自己的编号,从1到M
//c[i][t]表示在t时间内采药材获得的最大收益,但要求所采的药材编号不超过i
//根据第i棵药材,不采 或 采
//不采:直接用c[i-1][t]赋值
//采:用第i棵药材的价值加上 c[i-1][t-Shi[i]],既然决定采第i棵药材,那么总时间必定会减少Shi[i],
//我们能用剩下的时间t-Shi[i]采药
//c[i][t]=max(c[i-1][t],Jia[i]+c[i-1][t-Shi[i]])
int  proceed(int i,int t){

//如果只有权采编号为1的药材,判断它能不能采得了
if (i==1)
{
if(t>=Shi[1])
c[i][t]=Jia[1];
else
c[i][t]=0;//初始情况下c[i][t]是-1,把它置零表示该结点已经访问过了
}
else{
//如果还没决定在t时间内编号小于i的药材采集方案,先做出决定
if (c[i-1][t]==-1)
{
proceed(i-1,t);
}
//更新
c[i][t]=max(c[i-1][t],c[i][t]);

//判断第i棵药材要不要采

//注意!!!
//此处必须检查t>Shi[i],你要确保决定采第i棵药材后还剩下时间,否则
//数组二维越界,而编译器不报错,会调很久
if (t-Shi[i]>=0)
{
if (c[i-1][t-Shi[i]]==-1)
{
proceed(i-1,t-Shi[i]);
}
c[i][t]=max( c[i][t]  ,  c[i-1][t-Shi[i]]+Jia[i]   );
}
}
return c[i][t];
}
int max(int a,int b){
return a>b?a:b;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  01背包 动态规划