2022 icpc杭州站 C. No Bug No Game - 背包dp

题面

分析

能拿整个 p i p_i pi的就拿整个的,不能拿了可以拿一部分的,因此可以分成0和1两种情况,0表示拿整个的,1表示还可以拿部分的,两种情况放在一起做一遍01背包,找到最大价值。

代码
cpp 复制代码
#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 3010;

int dp[N][N][2];
int w[N][20];
int p[N];

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    int sum = 0;
    for(int i = 1; i <= n; i ++) {
        cin >> p[i];
        sum += p[i];
        for(int j = 1; j <= p[i]; j ++) cin >> w[i][j];
    }
    if(sum <= m) {
        int ans = 0;
        for(int i = 1; i <= n; i ++) ans += w[i][p[i]];
        cout << ans << "\n";
        return 0;
    }
    memset(dp, -0x3f, sizeof dp);
    dp[0][0][0] = 0;
    for(int i = 1; i <= n; i ++) {
        for(int j = 0; j <= m; j ++) {
            dp[i][j][0] = dp[i - 1][j][0];
            dp[i][j][1] = dp[i - 1][j][1];
            if(j >= p[i]) {
                dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - p[i]][0] + w[i][p[i]]);
                dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - p[i]][1] + w[i][p[i]]);
            }
            for(int k = 1; k < p[i]; k ++) {
                if(j >= k) dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k][0] + w[i][k]);
            }
        }
    }
    cout << max(dp[n][m][0], dp[n][m][1]) << "\n";
}
相关推荐
Jia ming5 分钟前
C语言实现日期天数计算
c语言·开发语言·算法
xh didida12 分钟前
C++ -- string
开发语言·c++·stl·sring
m晴朗35 分钟前
测试覆盖率从35%到80%:我用AI批量生成C++单元测试的完整方案
c++·gpt·ai
无限进步_38 分钟前
【C++&string】大数相乘算法详解:从字符串加法到乘法实现
java·开发语言·c++·git·算法·github·visual studio
苏纪云1 小时前
蓝桥杯考前突击
c++·算法·蓝桥杯
W23035765731 小时前
经典算法详解:最长公共子序列 (LCS) —— 从暴力递归到动态规划完整实现
算法·动态规划·最长子序列
pzx_0011 小时前
【优化器】 随机梯度下降 SGD 详解
人工智能·python·算法
‎ദ്ദിᵔ.˛.ᵔ₎1 小时前
模板template
开发语言·c++
charlie1145141911 小时前
通用GUI编程技术——图形渲染实战(二十九)——Direct2D架构与资源体系:GPU加速2D渲染入门
开发语言·c++·学习·架构·图形渲染·win32
小肝一下1 小时前
每日两道力扣,day8
c++·算法·leetcode·哈希算法·hot100