您的位置:首页 > 其它

Codeforces Round #286 (Div. 2) C Mr. Kitayuta, the Treasure Hunter ( DP )

2015-01-22 19:46 369 查看
题目链锁: http://codeforces.com/contest/505/problem/C

题意:

有30001个岛,0~30000, 给出n个岛上有宝藏,第一步跳跃距离为d,假设上一步跳跃距离为l,则当前可以跳l-1,l,l+1的距离

dp[i][j]表示在第i个点,上一步的跳跃距离l与第一步的跳跃距离相差为j,即 l = j + d



dp[i+l-1][j-1] = max ( dp[i+l-1][j-1], dp[i][j] + cnt[i+l-1] );

dp[i+l][j] = max( dp[l+i][j], dp[i][j] + cnt[i+l] );

dp[i+l+1][j+1] = max( dp[i+l+1][j+1], dp[i][j] + cnt[i+l+1] );

由于 ( d ) + ( d + 1 ) + ( d + 2 ) + ..... + ( d + 250 ) > 251d + 30000 所以取偏移量250;

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

#define inf 0x3f3f3f3f
#define eps 1e-9
#define mod 1000000007
#define FOR(i,s,t) for(int i = s; i < t; ++i )
#define REP(i,s,t) for( int i = s; i <= t; ++i )
#define LL long long
#define ULL unsigned long long
#define pii pair<int,int>
#define MP make_pair
#define lson id << 1 , l , m
#define rson id << 1 | 1 , m + 1 , r
#define maxn ( 30000+10 )
#define maxe ( 200+10 )

int dp[maxn][600], cnt[maxn];

int main () {
int n, d;
while( cin>>n>>d ) {
memset( cnt, 0, sizeof( cnt ) );
for( int i = 0; i < n; ++i ) {
int x;
scanf("%d", &x );
++cnt[x];
}
memset( dp, -1, sizeof( dp ) );
dp[d][250] = cnt[d];
int ans = cnt[d];
for( int i = d; i <= 30000; ++i ) {
for( int j = 0; j <= 500; ++j ) {
if( dp[i][j] == -1 ) continue;
int l = d + ( j - 250 );
if( l > 0 && i + l <= 30000 ) {
dp[i+l][j] = max( dp[l+i][j], dp[i][j] + cnt[i+l] );
ans = max( ans, dp[i+l][j] );
}
if( l - 1 > 0 && i + l - 1 <= 30000 ) {
dp[i+l-1][j-1] = max( dp[i+l-1][j-1] , dp[i][j] + cnt[i+l-1] );
ans = max( ans, dp[i+l-1][j-1] );
}
if( l + 1 <= 30000 && l + 1 > 0 && i + l + 1 <= 30000 ) {
dp[i+l+1][j+1] = max( dp[i+l+1][j+1], dp[i][j] + cnt[i+l+1] );
ans = max( ans, dp[i+l+1][j+1] );
}

}
}
printf("%d\n", ans );
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: