zoukankan      html  css  js  c++  java
  • 跳跃

    C 跳跃
    文件名 输入文件 输出文件 时间限制 空间限制
    jump.cpp/c/pas jump.in jump.out 1s 512MB
    题目描述
    美丽国有 n 座小岛。这些小岛排成了一条直线,依次编号为 0,1,2,3... 有的小岛
    上有金块,有的小岛上没有。美丽国有一个巨人 Bob,有一天他决定从第 0 个岛开
    始,一直往后跳,看看自己能收集多少金块。
    当然,Bob 不是没有目的性的乱跳;相反,Bob 的跳跃要满足以下规则:
    • 首先 Bob 从 0 跳到 d 岛屿
    • 假如 Bob 上一次跳了 l 步,则 Bob 下一次可以选择跳 l、l − 1、l + 1 步。注
    意:所跳的步数不能小于 1,即如果上一次跳跃的步数为 1,下一次跳跃的步
    数只能是 1 或者 2。
    在这样的规则下,Bob 想知道,他最多能拿到多少金块?
    输入格式
    输入第一行两个整数 n,d,分别表示有金块的岛屿的个数,和 Bob 第一步要
    跳的步数。
    接下来 n 行,每行一个整数 id,表示编号为 id 的岛屿上有金块。
    输出格式
    输出仅一行,表示 Bob 最多能收集多少金块。
    样例输入 1
    4 10
    10
    21
    27
    27
    6
    样例输出 1
    3
    样例输入 2
    8 8
    9
    19
    28
    36
    45
    55
    66
    78
    样例输出 2
    6
    数据范围
    对于 30% 的数据,1 ≤ n,d,id ≤ 100
    对于 70% 的数据,1 ≤ n,d,id ≤ 1000
    对于 100% 的数据,1 ≤ n,d,id ≤ 30000

    我首先写了个记忆化搜索,想写dp但是不会写啊。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int maxn;
    int n,d;
    int w[2009];
    int ans;
    int f[1009][1009];
    int dfs(int x,int tot,int last)
    {
        if(x>maxn)
        {
            ans=max(ans,tot);
            return tot;
        }
        if(f[x][last])    return f[x][last];//后面的都搜过就不搜了
        
        for(int i=max(1,last-1);i<=last+1;i++)
            f[x][last]=max(f[x][last],dfs(x+i,tot+w[x+i],i));
        return tot;
    }
    int main()
    {
        freopen("jump.in","r",stdin);
        freopen("jump.out","w",stdout);
        scanf("%d%d",&n,&d);
        for(int i=1,x;i<=n;i++)
        {
            scanf("%d",&x);
            w[x]++;maxn=max(maxn,x);
        }
        dfs(d,w[d],d);
        cout<<ans;
        return 0;
    }

    dp从后向前搜,f[i][j]表示当前在位置i,接下来走j步,回溯回来能拿多少金币。

      转移方程是

      f[i][j]=a[i]+max(f[i+j][j],f[i+j][j+1],f[i+j][j-1]).

    [#include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int maxn;
    int n,d;
    int w[2009];
    int ans;
    int f[1009][1009];
    int dfs(int x,int tot,int last)
    {
        if(x>maxn)
        {
            ans=max(ans,tot);
            return tot;
        }
        if(f[x][last])    return f[x][last];
        
        for(int i=max(1,last-1);i<=last+1;i++)
            f[x][last]=max(f[x][last],dfs(x+i,tot+w[x+i],i));
        return tot;
    }
    int main()
    {
        freopen("jump.in","r",stdin);
        freopen("jump.out","w",stdout);
        scanf("%d%d",&n,&d);
        for(int i=1,x;i<=n;i++)
        {
            scanf("%d",&x);
            w[x]++;maxn=max(maxn,x);
        }
        dfs(d,w[d],d);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    linux 服务发布脚本升级,远程发布,指定拉取远程dev,test等分支代码
    linux 执行脚本1.补充命令 2.后台执行
    centos7 操作防火墙
    复制目录及其子目录下所有文件DOC
    总结
    nmon监控与 nmon analyser分析
    nginx配置文服
    单字段去重 distinct 返回其他多个字段
    二维数组怎样进行遍历
    Socket与URL通信比较
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7724839.html
Copyright © 2011-2022 走看看