• Codeforces 505C Mr. Kitayuta, the Treasure Hunter:dp【考虑可用范围】


    题目链接:http://codeforces.com/problemset/problem/505/C

    题意:

      有n个宝石,分别在位置p[i]。(1 <= n,p[i] <= 30000)

      初始时你在位置0,第一次走可以往前跳d的距离。

      从第二次跳开始,如果前一次跳的距离是x,这一次跳的距离只能是x-1,x,x+1中的一种。

      没每跳到一个地方,会获得那里的所有宝石。

      问你最多能拿到多少宝石。

    题解:

      表示状态:

        dp[i][j] = max gems

        表示初始在位置i,上一次跳的距离为j,在这以及之后所能拿到的最大价值。

      找出答案:

        ans = dp[d][d]

      如何转移:

        dp[i][j] = max dp[i+j-1][j-1]

        dp[i][j] = max dp[i+j][j]

        dp[i][j] = max dp[i+j+1][j+1]

        然而O(N^2)过不了……

        因为每次跳的距离最多变化1,所以当n=30000时,跳的距离变化小于250,需要用到的j∈[d-250, d+250]。

        精确一些就是j∈[d-k, d+k],其中k = ((sqrt(8n+1)-1)/2)+5。

        将所有j映射到[0, 2k]的范围内,这样时间和空间就都能满足了。

      边界条件:

        if(i>maxd) dp[i][j] = 0

        maxd是有宝石的最远距离。

        当i>maxd时,之后不可能有任何收获。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <math.h>
     5 #define MAX_N 30005
     6 #define MAX_V 1005
     7 #define cal(x) ((x)-d+k)
     8 
     9 using namespace std;
    10 
    11 int n,d,k;
    12 int maxd=0;
    13 int a[MAX_N];
    14 int dp[MAX_N][MAX_V];
    15 
    16 int dfs(int i,int j)
    17 {
    18     if(i>maxd) return 0;
    19     if(dp[i][cal(j)]!=-1) return dp[i][cal(j)];
    20     if(j-1>0) dp[i][cal(j)]=max(dp[i][cal(j)],dfs(i+j-1,j-1)+a[i]);
    21     dp[i][cal(j)]=max(dp[i][cal(j)],dfs(i+j,j)+a[i]);
    22     dp[i][cal(j)]=max(dp[i][cal(j)],dfs(i+j+1,j+1)+a[i]);
    23     return dp[i][cal(j)];
    24 }
    25 
    26 int main()
    27 {
    28     cin>>n>>d;
    29     memset(a,0,sizeof(a));
    30     int x;
    31     for(int i=1;i<=n;i++)
    32     {
    33         cin>>x;
    34         a[x]++;
    35         maxd=max(maxd,x);
    36     }
    37     k=(int)((sqrt(n*8+1)-1.0)/2.0)+5;
    38     memset(dp,-1,sizeof(dp));
    39     cout<<dfs(d,d)<<endl;
    40 }
  • 相关阅读:
    header
    panel----单个基础版
    vue-demo
    js不同类型变量比较
    reset.css
    关于各个浏览器的兼容问题
    git
    AMD与CMD区别
    喜欢前端的看过来哦
    js中数组去重的几种方法
  • 原文地址:https://www.cnblogs.com/Leohh/p/8194380.html
Copyright © 2020-2023  润新知