题解-猴子吃香蕉
【问题描述】
一只猴子找到了很多香蕉树,这些香蕉树都种在同一直线上,而猴子则在这排香蕉树的第一棵树上。这只猴子当然想吃尽量多的香蕉,但它又不想在地上走,只想从一棵树跳到另一棵树上.同时猴子的体力有限,它不能一次跳得太远或跳得次数太多,每当他跳到一棵树上,就会把那棵树上的香蕉都吃掉。那么,它最多能吃多少个香蕉呢?
【输入格式】
输入第一行为三个整数,分别是香蕉树的棵数N,猴子每次跳跃的最大距离D,最多跳跃次数M.
下面N行每行包括两个整数,ai,bi分别表示每棵香蕉树上的香蕉数,以及这棵树到猴子所在树的距离。输入保证这些树按照从近到远排列,并且没有两棵树在同一位置。b0总是为0 .
【输出格式】
输出只有一行,包含一个整数,为猴子最多能吃到的香蕉数。
【输入样例】
5 5 2
6 0
8 3
4 5
6 7
9 10
【输出样例】
20
思路
//分析:原始状态是在第一棵树走了0步,得到香蕉a[1]个。
//接着可以表示dp[i][j]表示在第i棵树上,此时走了第j步。那么这个状态往后怎么推呢?考虑此时状态,若跳到这里,那就是dp[k][j-1]+a[i];j-1代表前面的j-1次跳跃,k代表可以从哪一颗树上跳过来,但此时要满足b[i]-b[k]<=d;
Ac code:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,ans,maxx,a[10005],b[10005],dp[10005][10005];
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
for(int i=1;i<=105;i++)
for(int j=0;j<=105;j++)
dp[i][j]=-1111;//注意既然要最小就尽量小
dp[1][0]=a[1];//初始状态
maxx=a[1];//注意maxx要赋初值
for(int i=2;i<=n;i++)
{
for(int j=1;j<=k;j++)//j枚举跳的步数
{
for(int l=1;l<i;l++)
{
if(b[i]-b[l]<=m)//验证
{
dp[i][j]=max(dp[i][j],dp[l][j-1]+a[i]);//dp转移方程
maxx=max(maxx,dp[i][j]);//更新答案
}
}
}
}
cout<<maxx;
return 0;
}