辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。
为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了
一个难题。医师把他带到个到处都是草药的山洞里对他说:“孩子,这个山洞
里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。
我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明
的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
Input
输入的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),T代表
总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括
两个在1到100之间(包括1和100)的的整数,分别表示采摘某株草药的时间和
这株草药的价值。
Output
输出只包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。
Sample Input
70 3
71 100
69 1
1 2
Sample Output
3
这道题我在做的时候很崩溃,因为一直WA, 最后不得不在网上寻找大佬的代码借鉴,动态规划的关系式一直想不到,不过这种算法在理解上还要多下功夫!!!
三步走
首先我们定义二维数组dp[i][j]为在拥有j长度时间时采集第i种草药所能获得的最大价值
其次我们寻找数组元素之间的关系式,我们知道,面对一种草药,我们的选择只有两种,
采 或者 不采 ,
- 那么如果我们选择采的话,我们的dp[ i ][ j ]便于dp[ i -1 ][ j -a[l][1] ] 产生了关系
因为现在的状态就变成了上一个状态(消耗时间后)的最大价值加上我们所获得的草药价值
反之如果我们不采,那么我们的dp[ i ][ j ]与上一个状态保持一致不变即可
最后是初始化,我们将dp数组初始化为0即可,因为没有采集草药即价值为0
int max(int a,int b) { if(a>b) return a; else return b; } #include<stdio.h> int t,n; int a[10500][2]; int dp[10500][10500];定义二维数组dp[i][j]为在拥有j长度时间时采集第i种草药所能获得的最大价值 int main() { int i,l,y; scanf("%d%d",&t,&n); for( i=1;i<=n;i++) scanf("%d%d",&a[i][1],&a[i][2]); 输入草药信息 for( l=1;l<=n;l++) for( y=t;y>0;y--) { if(a[l][1]<=y)//该种草药所需时间小于等于我们拥有的时间 { dp[l][y]=max(dp[l-1][y],dp[l-1][y-a[l][1]]+a[l][2]);//看 采 或者 不采 该草药的价值对比 } else dp[l][y]=dp[l-1][y];//该种草药所需时间大于我们拥有的时间(此时状态与上一个状态保持相同) } printf("%d",dp[n][t]); }