蓝桥杯-第二点五个不高兴的小明-动态规划

题目:http://lx.lanqiao.cn/problem.page?gpid=T770

思路:

令dp[i][j]表示第i次跳跃跳到位置j时跳过的方格权重值

对于第i次跳跃。由于一次最多跳p格,而且不会跳出头,所以它的可能位置为[i,min(i*p)]

如果当前处在位置j,那么它上一次的位置 bef可能在[max(0,j-p),j-1] 上一次的位置不可能小于0

转移方程 

dp[i][j]=max(dp[i][j], dp[i-1][bef]+w[j])

需要注意的是,题目中的w[i]可能为负数,那么在转移过程中可能出现怎么跳都比不跳更划算的情况,导致出现问题。所以需要预处理数据,把所有w[i]加上1000成为正数,最后结果里减去对应的多加的数。

 1 #include <iostream>
 2 #include <stdio.h>
 3 //#define LOCAL
 4 using namespace std;
 5 typedef long long ll;
 6 const int mx=1000+10;
 7 const int inf=-1005*1005;
 8 int n, p, t;
 9 int w[mx];
10 int dp[mx][mx];//dp[i][j] i times j sub
11 void solve(){
12     cin>>n>>p>>t;
13     for(int i=1;i<=n;i++) cin>>w[i], w[i]+=1000;
14     for(int i=1;i<=t;i++)
15         for(int j=1;j<=n;j++)
16         dp[i][j]=inf;
17     t--;
18     for(int i=1;i<=t;i++){//time
19         for(int j=i;j<=min(n,i*p);j++){//sub
20             for(int bef=max(0,j-p);bef<=j-1;bef++){
21                 dp[i][j]=max(dp[i][j], dp[i-1][bef]+w[j]);
22             }
23         }
24     }
25     int ans=inf;
26     for(int i=n;i>=n-p+1;i--){
27         ans=max(dp[t][i], ans);
28     }
29     ans-=1000*t;
30     cout<<ans<<endl;
31 }
32 
33 int main(){
34     #ifdef LOCAL
35     FILE *fp=freopen("1.txt", "r", stdin);
36     #endif // LOCAL
37     solve();
38     #ifdef LOCAL
39     fclose(fp);
40     #endif // LOCAL
41     return 0;
42 }

 

posted @ 2021-03-06 21:08  反射狐  阅读(208)  评论(0)    收藏  举报