51nod1455(dp)

Posted ygeloutingyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod1455(dp)相关的知识,希望对你有一定的参考价值。

题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1455

 

题意: 中文题诶~

 

思路: dp

1 <= n, d <= 3e4, 直接用 dp[i][j] 存储从上一个岛屿经过 距离 j 到达岛屿 i 的最大收获显然是不行的.  可以令 j‘ 为当前移动距离  j 与 d 的差值, 即 dp[i][j‘] 存储从上一个岛屿经过距离 |j‘ + d| 到达岛屿 i 最大收获. 因为 d 每次只能加或者减 1, 所以偏移量 j‘ 的范围在 -250 ~ 250 之间. 可以给所有偏移量加 300 使其全部变成正数, 后面计算时再减回去即可. 那么动态转移方程为:

  int next = i + j + d - 300;

  if(next < MAXN && next - i) dp[next][j] = max(dp[next][j], dp[i][j] + vis[next]);

  if(next + 1 < MAXN && next - i + 1) dp[next + 1][j + 1] = max(dp[next + 1][j + 1], dp[i][j] + vis[next + 1]);

  if(next - 1 >= 1 && next < MAXN && next - i - 1 >= 1) dp[next - 1][j - 1] = max(dp[next - 1][j - 1], dp[i][j] + vis[next - 1]);

 

代码:

技术分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int MAXN = 3e4 + 1;
 7 int dp[MAXN][610], vis[MAXN];//dp[i][j]存储从上一个岛屿经过距离|j+d|到达岛屿i最大收获,其中j为当前移动步数与d的差值
 8 
 9 int main(void){
10     int n, d, x;
11     memset(dp, -1, sizeof(dp));
12     scanf("%d%d", &n, &d);
13     for(int i = 0; i < n; i++){
14         scanf("%d", &x);
15         vis[x]++;
16     }
17     dp[d][300] = vis[d];//所有偏移量+300,但是其他dp值为0,所以不必额外处理
18     int ans = vis[d];
19     for(int i = 1; i < MAXN; i++){
20         for(int j = 0; j < 600; j++){
21             if(dp[i][j] == -1) continue;
22             int next = i + j + d - 300;//这里的j表示+300后的偏移量,所以要减回去
23             if(next < MAXN && next - i){
24                 dp[next][j] = max(dp[next][j], dp[i][j] + vis[next]);
25                 ans = max(ans, dp[next][j]);
26             }
27             if(next + 1 < MAXN && next - i + 1){
28                 dp[next + 1][j + 1] = max(dp[next + 1][j + 1], dp[i][j] + vis[next + 1]);
29                 ans = max(ans, dp[next + 1][j + 1]);
30             }
31             if(next - 1 >= 1 && next < MAXN && next - i - 1 >= 1){
32                 dp[next - 1][j - 1] = max(dp[next - 1][j - 1], dp[i][j] + vis[next - 1]);
33                 ans = max(ans, dp[next - 1][j - 1]);
34             }
35         }
36     }
37     cout << ans << endl;
38     return 0;
39 }
View Code

 

以上是关于51nod1455(dp)的主要内容,如果未能解决你的问题,请参考以下文章

51Nod 1450 闯关游戏 —— 期望DP

51nod 1021 石子归并 (动态规划 简单代码)

51Nod 1042 数字0-9的数量(数位DP)

51Nod 1021~1023 石子合并 (逐步加强版) dp

51nod 矩阵取数

[51Nod 1301] 集合异或和 (dp)