GDOI - 2009 猴子 动态规划 重庆一中高2018级竞赛班第八次测试 2016.8.7 Problem 1

来源:互联网 发布:天猫app实时调研数据 编辑:程序博客网 时间:2024/05/10 07:33

【问题描述】
一只猴子找到了很多香蕉树,这些香蕉树都种在同一直线上,而猴子则在这排香蕉树的第一棵树上。这只猴子当然想吃尽量多的香蕉,但它又不想在地上走,只想从一棵树跳到另一棵树上.同时猴子的体力有限,它不能一次跳得太远或跳得次数太多,每当他跳到一棵树上,就会把那棵树上的香蕉都吃掉。那么,它最多能吃多少个香蕉呢?

【输入格式】
输入第一行为三个整数,分别是香蕉树的棵数N,猴子每次跳跃的最大距离D,最多跳跃次数M.
下面N行每行包括两个整数,ai,bi分别表示每棵香蕉树上的香蕉数,以及这棵树到猴子所在树的距离。输入保证这些树按照从近到远排列,并且没有两棵树在同一位置。b0总是为0.

【输出格式】
输出只有一行,包含一个整数,为猴子最多能吃到的香蕉数。

【输入样例】

5 5 26 08 34 56 79 10

【输出样例】

20

【数据范围】
ai<=10000,d<=10000
对于30%的数据,有M< N <=10,bi<=100
对于50%的数据,有M< N <=30,bi<=1000
对于100%的数据,有M< N <=100,bi<=10000

思路:求最大值一开始就想到了动态规划,但是我设的状态函数为f[i][j][k]:前i棵树,跳跃次数不超过j次,坐标不超过k时的最大值。记录坐标根本没什么用。
所以正解为f[i][j]:跳到第i棵树时跳跃了j次获得的最大值。若设为f[i][j]:跳跃i次到第j棵树上的最大值,还可使用滚动数组进行优化。
状态转移方程为:f[i][j]=max(f[i][j],f[i-1][k]+a[j]) (0<=k<=j-1 && b[j]-b[k]<=d)

/*    Name: monkey.cpp    Copyright: Twitter & Instagram @stevebieberjr    Author: @stevebieberjr    Date: 07/08/16 19:26*/#include<cstdio>#include<cstring>#include<algorithm>#define inf 0X3F3F3F3Fusing namespace std;int n,d,m;struct tree{    int a,b;}t[105];int f[2][105]; //跳跃i次到第j棵树上的最大值 int main(){    freopen("monkey.in","r",stdin);    freopen("monkey.out","w",stdout);    scanf("%d%d%d",&n,&d,&m);    for(int i=1;i<=n;i++)    {        scanf("%d%d",&t[i].a,&t[i].b);    }    memset(f,-0X3F,sizeof(f));    for(int i=0;i<2;i++)    {        f[i%2][1]=t[1].a;    }    int ans=t[1].a;    for(int i=1;i<=m;i++)    {        for(int j=2;j<=n;j++)        {            int T=-inf;            for(int k=j-1;k>=0 && t[j].b-t[k].b<=d;k--)            {                T=max(T,f[(i-1)%2][k]+t[j].a);            }            f[i%2][j]=T;            ans=max(ans,f[i%2][j]);        }    }    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击