• 试题 算法提高 第二点五个不高兴的小明(dp)


    问题描述
      有一条长为n的走廊,小明站在走廊的一端,每次可以跳过不超过p格,每格都有一个权值wi。
      小明要从一端跳到另一端,不能回跳,正好跳t次,请问他跳过的方格的权值和最大是多少?
    输入格式
      输入的第一行包含两个整数n, p, t,表示走廊的长度,小明每次跳跃的最长距离和小明跳的次数。
      接下来n个整数,表示走廊每个位置的权值。
    输出格式
      输出一个整数。表示小明跳过的方格的权值和的最大值。
    样例输入
    8 5 3
    3 4 -1 -100 1 8 7 6
    样例输出
    12
    数据规模和约定
      1<=n, p, t<=1000, -1000<=wi<=1000。
    思路
    dp[i][j]代表第i位置跳到目标位置消耗j次跳的最大权值,倒数的后p+1个可以一步跳到一端,所以初始化dp[i][1]=w[i];
    从后往前递推,最后输出dp[0][t]即是所求答案。p可能比n大,注意数组越界。
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    ll w[1005];
    ll dp[1005][1005];
    ll n,p,t;
    const ll inf=0x3f3f3f;
    int main(){
        cin>>n>>p>>t;
        for(int i=1;i<=n;i++)cin>>w[i];
        for(int i=n;i>=n-p&&i>=0;i--)dp[i][1]=w[i];///目标即是达到跳数为1时达到这些点
        for(int i=n;i>=0;i--){
            for(int j=2;j<=t;j++){///最后到达剩余1次跳数的格子
                dp[i][j]=-inf;///先置为无法到达(跳数过多or跳数过少)
                for(int k=1;k<=p&&i+k<=n;k++){
                    dp[i][j]=max(dp[i][j],dp[i+k][j-1]);
                }
                if(dp[i][j]!=-inf)dp[i][j]+=w[i];///如果可以到达,加上本身的格子
            }
        }
        cout<<dp[0][t]<<endl;///从0位置花费t次到达另一边
        return 0;
    }

    也可以记忆化搜索

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long int ll;
    ll w[1005];
    ll dp[1005][1005];
    ll n,p,t;
    const ll inf=0x3f3f3f;
    ll maxx=-inf;
    int dfs(int m,int step){
        if(m>n+1||step<0)return -inf;///超过位置or步数不足
        if(step>n+1-m)return -inf;///剪枝,步数过多
        if(dp[m][step]!=-1)return dp[m][step];///更新过最优值,直接返回
        if(step==1){///剩余1步时
            if(n-m<=p)return dp[m][step]=w[m];///m跳到另一端小于等于p格
            else return -inf;///返回不可达
        }
        int sum=-inf;
        for(int i=1;i<=p;i++){
            sum=max(sum,dfs(m+i,step-1));
        }
        if(sum!=inf)sum+=w[m];///加上本身的权值
        return dp[m][step]=sum;
    }
    int main(){
        cin>>n>>p>>t;
        memset(dp,-1,sizeof(dp));
        for(int i=1;i<=n;i++)cin>>w[i];
        cout<<dfs(0,t)<<endl;
        return 0;
    }
     
  • 相关阅读:
    MS SQL 数据库状态为SUSPECT(可疑)的处理方法
    根據名稱查找文件,并移動
    deploy war to weblogic via script(shell)
    maven打包时包含所有依赖的jar
    随笔
    如何在Oracle SQL Developer對Procedure除錯
    git常用命令和記錄
    英語筆記
    IDEA設置
    mysql常用命令和记录
  • 原文地址:https://www.cnblogs.com/mohari/p/13541923.html
Copyright © 2020-2023  润新知