@钓鱼II (DP)

版权声明:岂曰无衣,与子同袍 https://blog.csdn.net/sizaif/article/details/82780789

题目描述

在一条水平路边,有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;
}

猜你喜欢

转载自blog.csdn.net/sizaif/article/details/82780789