cf#186-C. Mr. Kitayuta, the Treasure Hunter-dp(预推断+offset)

http://codeforces.com/problemset/problem/505/C

题意:

有30001个岛屿,下标为0~30000,给n个数告诉你有n份宝藏藏在哪些岛上。 

你从0往下标大的方向跳,第一步跳的距离为d。

如果上一步跳的距离为D,这一步就可以跳D-1或D或D+1(但是距离必须大于0)。

问最多拿到多少宝藏。


思路:

dp[i][j] 表示 刚到达第i岛屿,从上一岛屿跳过来的步长是D+j单位距离 ,

那么我们可以推得三种后继情况

int dis=i+D+j,  

1·  这一步选择仍跳D+j距离,则dp[dis][j]=max(dp[dis][j],dp[i][j]+vis[dis]);

2·  这一步选择跳D+j+1距离,则dp[dis+1][j+1]=max(dp[dis+1][j+1],dp[i][j]+vis[dis+1]);

3·  这一步选择跳D+j-1距离,则dp[dis-1][j-1]=max(itself,dp[i][j]+vis[dis-1]);


注意每一步要判断即将到达的位置是否<=30000


初始化dp数组为-1,要递推的话肯定是从第0个岛屿推起,也就是初始化dp[D][0]=vis[D]   // 其实是dp[D][250]=vis[250];


因为len=30000,并且每次步长最多递增1,1+2+3+...+n=n*(n+1)/2<=30000,

n最多不超过250, 也就是最长的步长不会超过D+250,

当然如果每次递减1,最短的步长也不会少于D-250

所以我们枚举的 的j,只需要从-250到250,显然数组下标为负数不方便,我们加250的offset,把j变成0~500,

而每次 从上一岛屿跳过来的步长就变成了D+j-250


在递推过程中,第三种情况要注意加判断,因为第三种是步长不断减小,可能减成负数了。。。我们令dis-1>i,即距离差为正即可



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001; 
int max(int a,int b)
{return a<b?b:a;}
int max(int a,int b,int c)
{return max(a,max(b,c));}
int vis[30005];
int dp[30005][520];
int main()
{
	//vis[i]  //第i岛屿的gem数
	//dp[i][j] //到达第i处, 此时走j步,收集到的gem
	int n,D;
	cin>>n>>D;
	int i,j,tmp;
	memset(dp,-1,sizeof(dp));		//初始化为-1
	for (i=1;i<=n;i++)
	{
		scanf("%d",&tmp);
		vis[tmp]++; 
	}
	int maxx=vis[D];
	dp[D][250]=vis[D];

	for (i=D;i<=30000;i++)
	{
		for (j=1;j<=500;j++)
		{
			if (dp[i][j]==-1)continue;
			int dis=i+D+j-250;
			if (dis<=30000)
			{
				dp[dis][j]=max(dp[dis][j],dp[i][j]+vis[dis]);
				maxx=max(maxx,dp[dis][j]);
			}
			if (dis+1<=30000)
			{
				dp[dis+1][j+1]=max(dp[dis+1][j+1],dp[i][j]+vis[dis+1]);
				maxx=max(maxx,dp[dis+1][j+1]);
			}
			if (dis-1>i&&dis-1<=30000)//要求步长为正数,即dis-1>i
			{
				dp[dis-1][j-1]=max(dp[dis-1][j-1],dp[i][j]+vis[dis-1]);
				maxx=max(maxx,dp[dis-1][j-1]);
			}
		}
	}
	printf("%d\n",maxx);
	
	return 0;
	
}





  

你可能感兴趣的:(cf#186-C. Mr. Kitayuta, the Treasure Hunter-dp(预推断+offset))