有一条长为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。
思路:
本题需要选择一步的距离,在规定步数下,求最优解,所以有两种解法,DFS(记忆化) 和 DP。
DFS+记忆化
数据说明:
maxn是数据范围, INF是最大值 (个人习惯)
n:一共多少个点 p:最远一步可以走多远 t:能走几步
w[i] :点权 dp[i][j] 从i点还剩j步的最大值
index就是i step就是j
Code:
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const ll INF = 0x7f;
const ll maxn = 1005; //数据范围
ll n,p,t;
ll w[maxn];
ll dp[maxn][maxn];
ll dfs(ll index,ll step){
if(dp[index][step]!= -1)return dp[index][step]; //剪枝
if(step*p < n-index+1)return -INF; //太远 走不到
if(step>n-index+1)return -INF; //步数过多
if(step == 1){
if(n-index+1 <= p) return dp[index][1]=w[index]; //只剩一步的情况下能走到
else return -INF; //不能走到
}else{
ll sum = -INF;
for(ll i=index+1;i<=index+p && i<=n;i++)sum = max(sum,dfs(i,step-1)); //下一步走多远
if(sum!= -INF)sum+=w[index]; //下一步多远没有计算此步的距离
return dp[index][step] = sum; //记忆
}
}
int main()
{
cin>>n>>p>>t;
for(int i=1;i<=n;i++)cin>>w[i];w[0]=0;
memset(dp,-1,sizeof(dp));
cout<<dfs( 0 , t)<<endl; //从起点还有t步开始搜
return 0;
}
DP 动态规划
数据说明:
maxn是数据范围, INF是最大值 (个人习惯)
n:一共多少个点 p:最远一步可以走多远 t:能走几步
w[i] :点权 dp[i][j] 从i点还剩j步的最大值
思路:
①以为要求某个点到终点的最大值,所以我们应该从后往前递推 (第一层for)
②模拟能跳的次数 (第二层for)
③模拟跳跃的距离 (第三层for)
因为需要①,所以我们可以预处理只剩最后一步的情况,及终点向前移动p个位置点的初始值
接下来将每个点的值初始为 -INF 用于求最大值
dp[0][t]为答案
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 0x7f;
const int maxn = 1005;
ll n,p,t;
ll w[maxn]; //记录点的权值
ll dp[maxn][maxn]; //dp[i][j] 从i点跳j次可以到达终点的最大值
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]; //预处理后面只需要跳一部的情况
for(int i=n;i>=0;i--){
//一共n站
for(int j=2;j<=t;j++){
//模拟可以跳的次数
dp[i][j] = -INF;
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; //初始站跳 t 次的最大值
return 0;
}