题目描述
在一条水平路边,有n个钓鱼湖,从左到右编号为1,2,…,n。佳佳有H个小时的空余时间,他希望利用这个时间钓到更多的鱼。他从1出发,向右走,有选择的在一些湖边停留一定的时间(是5分钟的倍数)钓鱼。最后在某一个湖边结束钓鱼。佳佳从第i个湖到第i+1个湖需要走5×Ti分钟路,还测出在第i个湖停留,第一个5分钟可以钓到Fi条鱼,以后每再钓5分钟,可以钓到的鱼量减少Di,若减少后的鱼量小于0,则减少后的鱼量为0。为了简化问题,佳佳假定没有其他人钓鱼,也没有其他因素影响他钓到期望数量的鱼。请编程求出佳佳最多能钓鱼的数量。
输入
第一行一个整数n(2≤n≤100),表示湖的个数
第二行一个整数H(1≤H≤20),表示佳佳的空闲时间
第三行有n个整数,依次表示每个湖第一个5分钟能钓到鱼的数量
第四行有n个整数,依次表示以后的每5分钟钓鱼数量比前一个5分钟钓鱼数量减少的数量
第五行有n−1个整数,Ti表示由第i个湖到第i+1个湖需要花5×Ti分钟的路程
输出
输出只有一行,表示佳佳最多能钓鱼的数量。
样例输入
3 1 4 5 6 1 2 1 1 2
样例输出
35
提示
在第1个湖钓15分钟,共钓得4+3+2=9条鱼;
在第2个湖钓10分钟,共钓得5+3=8条鱼;
在第3个湖钓20分钟,共钓得6+5+4+3=18条鱼;
从第1个湖到第2个湖,从第2个湖到第3个湖,共用时间15分钟,共得35条鱼,并且这是最多的数量。
[思路]
考虑 DP
一个小时有12 个5 分钟, 按照 5 分钟为 计量单位,
dp[i][j][k] 三维数组 代表 在 第 i 个5 分钟 在 j 位置 呆了 k 个5 分钟 时 钓到最多的鱼 的数量.
那么 决策方案有两个, 要么 继续呆下去 或者 去下一个地方
dp[i+1][j][k+1] . 继续待在此地.
dp[i+t[j] ] [ j] [ 0] 去下一个地方
三维数组 开到 300
代码:
#include <bits/stdc++.h>
#include <stdio.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
typedef long long ll;
const int maxn = 1e5+10;
const int mod =1e9+7;
const int inf = 0x3f3f3f3f;
using namespace std;
int f[2200];
int d[2200];
int ti[2200];
int dp[300][110][300];
int main(int argc, char const *argv[])
{
int n;
scanf("%d",&n);
int h;
scanf("%d",&h);
rep(i,1,n) scanf("%d",&f[i]);
rep(i,1,n) scanf("%d",&d[i]);
rep(i,2,n) scanf("%d",&ti[i]);
int ans = 0;
memset(dp,-inf,sizeof(dp));
dp[0][1][0] = 0;
for(int i = 0 ; i <= h*12 ; i++)
{
for( int j = 1 ; j <= n ; j++ )
{
for(int k = 0 ; k <= h*12 ; k++)
{
int nowH = f[j]-k*d[j];
if( i+1 <= 12*h && k+1 <= 12*h)
{
dp[i+1][j][k+1] = max(dp[i+1][j][k+1],dp[i][j][k]+nowH);
}
if( i+1 <= 12*h && j+1 <=n)
{
dp[i+ti[j+1] ][j+1][0] = max(dp[ i+ti[j+1] ][j+1][0] ,dp[i][j][k]);
}
ans = max(ans,dp[i][j][k]);
}
}
}
printf("%d\n",ans );
return 0;
}