2022ICPC杭州站C(dp)

359 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

C - No Bug No Game

Putata is preparing the RPG Pro League (RPL) held by the International Computer Playing Company (ICPC). In this RPG game, the player will wear nn items at the same time. Each item can offer the player several points of power. There is a magic buff in the game, which can upgrade each item such that they can offer several points of bonus power.
However, the buff is limited, it can only buff at most kk points of power. Formally, assume the player is wearing nothing initially, and then will wear all the nn items one by one. The game server will scan through all these nn items one by one, according to the permutation that the player wears them. When the server is scanning the ii-th item, which can offer pip_i points of power, let sum=1j<ipjsum=\sum_{1\leq j<i}p_j denoting the total points of power scanned before:
If sum+piksum+p_i\leq k, the whole item will be upgraded. The buff will offer wi,piw_{i,p_i} points of bonus power. If sumksum\geq k, the item won't be upgraded. The buff will offer nothing. Otherwise, only a part of the item will be upgraded. The buff will offer wi,ksumw_{i,k-sum} points of bonus power. Putata is clever, he soon realized that he can adjust the permutation to wear these nn items to gain more points of bonus power! Unfortunately, Putata doesn't know the optimal permutation, please write a program to help him.
The behavior of the magic buff performed by the game server is a bug. The game code can work all thanks to bugs, so it is possible that wi,a>wi,bw_{i,a}>w_{i,b} where a<ba<b.

Code

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
const int N = 6010;

int a[N], f[N][N][2], p[N], s[N][N];

void solve() {
    int n, k; scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &p[i]);
        for(int j = 1; j <= p[i]; j++) {
            scanf("%d", &s[i][j]);
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <= k; j++) {
            f[i][j][0] = f[i-1][j][0];
            f[i][j][1] = f[i-1][j][1];
            if(p[i] <= j) {
                if(f[i-1][j-p[i]][1])
                f[i][j][1] = max(f[i][j][1], f[i-1][j - p[i]][1] + s[i][p[i]]);
                if(f[i-1][j-p[i]][0] || j == p[i])
                f[i][j][0] = max(f[i][j][0], f[i-1][j - p[i]][0] + s[i][p[i]]);
            }
            for(int l = 1; l < p[i] && l <= j; l ++) {
                if(f[i-1][j-l][0] || j == l)
                f[i][j][1] = max(f[i][j][1], f[i-1][j - l][0] + s[i][l]);
            }
        }
    }
    int res = f[n][k][1];
    for(int i = 0; i <= k; i++) res = max(res, f[n][i][0]);
    printf("%d", res);
}

int main() {
    int T = 1;
    // scanf("%d", &T);
    while(T--) solve();
}