码迷,mamicode.com
首页 > 其他好文 > 详细

CF ECR92 B.Array Walk

时间:2020-07-30 10:53:45      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:array   获得   and   lse   有一个   end   数组   bit   代码   

CF ECR92 B.Array Walk

技术图片

题目链接

B.Array Walk

题目概述

\(n\)个数,从第一个位置开始走,可以选择向左或者向右走,然后获得下一步到达的那个数的值,向左向右走之后的位置不能越界,并且不能连续向左走两次以上,也就是一次向左走之前一定有一次向右走的操作.现在要求恰好经过\(k\)次移动并且向左走的次数不超过\(z\),计算经过的数字之和的最大值.有\(t\)轮测试,每一轮测试的输入格式是先输入三个整数\(n,k,z\),然后输入\(n\)个整数,输出进过数字的和的最大值.每个参数的数据范围:

\[1 \le t \le 10^4,2\leq n \leq 10^5, 1\leq k \leq n-1, 0 \leq z \leq \min(5,k) \1 \leq a_i \leq 10^4, i=0,1,\dots,n\\sum_{i=0}^{k}n_i \leq 3\cdot10^5 \]

思路

使用dp,dp[i][j]这个数组的i表示移动的次数,j表示向左移的次数,在第i次移动时有两个选择向右移动,得到dp[i+1][j,此时的dp[i+1][j] = max(dp[i+1][j], dp[i][j]+buf[i-2*j+1]);这里面的i-2*j表示的是此时的位置,2*j表示向右移动一次和向左移动一次,buf[i-2*j+1]表示向右移动后下一个位置的值,这里面有一个约束条件i-2*j >= 0也就是回退的次数乘以2不能比此时可以移动的次数i大.如果此时回退的次数小于z-并且此时已经移动的次数i不大于k-2,那么可以向右移动一次再向左移动,然后移动次数加2,左移回退次数加1,得到dp[i+2][j+1],对应的语句是dp[i+2][j+1] = max(dp[i+2][j+1], dp[i][j]+buf[i-2*j+1]+buf[i-2*j]);

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
int buf[N];
int dp[N][10];

void solve(int n, int k, int z){
    memset(dp, 0, sizeof(dp));
    dp[0][0] = buf[0];
    for(int i = 0; i < k; ++i){
        for(int j = 0; j <= z; ++j){
            if( i - 2 * j < 0)
                break;
            // turn right
            dp[i+1][j] = max(dp[i+1][j], dp[i][j]+buf[i-2*j+1]);
            // turn right and turn left
            if( j < z && i + 2 <= k){
                dp[i+2][j+1] = max(dp[i+2][j+1], dp[i][j]+buf[i-2*j+1]+buf[i-2*j]);
            }
        }
    }
    int ans = 0;
    for(int i = 0; i <= z; i++){
        ans = max(ans, dp[k][i]);
    }
    // printf("%lld\n", ans);
    cout<<ans<<endl;
}

int main(int argc, char **argv){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    // scanf("%d", &t);
    cin>>t;
    while(t--){
        int n,k,z;
        // scanf("%d%d%d", &n, &k, &z);
        cin>>n>>k>>z;
        z = min(5,z);
        for(int i = 0; i < n; i++){
            // scanf("%lld", &buf[i]);
            cin>>buf[i];
        }
        solve(n,k,z);
    }
}

最初直接用scanf读的输入数据,然而莫名的竟然TLE,于是改为cin并且取消同步,结果就通过了.

其它

CF ECR92 B.Array Walk

标签:array   获得   and   lse   有一个   end   数组   bit   代码   

原文地址:https://www.cnblogs.com/2018slgys/p/13402257.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!