Loading

Educational Codeforces Round 92 (Rated for Div. 2) B. Array Walk 动态规划

给定一个长度为n的正数组,在这个数组上跑,每跑到一个点获得该点的分数。

有k次行动的机会,有最多z次返回的机会。且返回不得连续返回两次。

k <= n - 1, 1 <= z <= min(5,k)

首先此题背景和《乌龟棋》很相似,其次z的范围很小,可以考虑dp

dp[k][z]表示当前走了k步,返回了z步。

容易想到的贪心策略是如果要返回,必然在同一个点反复横跳。

转移方程

 dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + a[i - 2 * j + 1]);

 if (j < z && i + 2 <= k) dp[i + 2][j + 1] = max(dp[i + 2][j + 1], dp[i][j] + a[i - 2 * j + 1] + a[i - 2 * j]);

因此两重循环,枚举 i 0 ~ k  j 0 ~ z

此题有一定难度,很有教育意义!!

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define pb push_back
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define moD 1000000003
#define pii pair<ll,ll>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
typedef  long long ll;
typedef unsigned long long ull;
const ll MOD = 1e6 + 7;
const int maxn = 1e5 +5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
using namespace std;

ll mul(ll a, ll b, ll m) {
    ll res = 0;
    while (b) {
        if (b & 1) res = (res + a) % m;
        a = (a + a) % m;
        b >>= 1;
    }
    return res % m;
}

ll quickPower(ll a, ll b, ll m) {
    ll base = a;
    ll ans = 1ll;
    while (b) {
        if (b & 1) ans = mul(ans, base , m);
        base = mul(base, base , m);
        b >>= 1;
    }
    return ans;
}


int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

void Put(int x)  {
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}

int dp[maxn][6];
int a[maxn];

void solve() {
    memset(dp, 0, sizeof dp);
    int n, k, z;
    n = readint(), k = readint(), z = readint();
    for (int i = 0; i < n; i++) a[i] = readint();
    dp[0][0] = a[0];
    for (int i = 0; i < k; i++) {
        for (int j = 0; j <= z && 2 * j <= i; j++) {
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + a[i - 2 * j + 1]);
            if (j < z && i + 2 <= k) dp[i + 2][j + 1] = max(dp[i + 2][j + 1], dp[i][j] + a[i - 2 * j + 1] + a[i - 2 * j]);
        }
    }
    int ans = -1;
    for (int i = 0; i <= z; i++) ans = max(dp[k][i], ans);
    Put(ans);
    puts("");
}




int main() {
    int T;
    cin >> T;
    while (T--) solve();
}

 

posted @ 2020-07-30 09:42  MQFLLY  阅读(309)  评论(0编辑  收藏  举报