当前位置:首页 > 入门组 > CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用

6个月前 (06-07)

CSP-J 2019纪念品题解(洛谷P5662):动态规划+完全背包问题的实战应用  动态规划 完全背包问题 算法题解 第1张

一、题目解读

2019年CSP-J的“纪念品”问题(对应洛谷P5662)要求玩家在T天内通过买卖纪念品最大化金币收益。每天可交易N种商品,需计算最优策略下的最终金币数。题目强调动态规划思维与资源分配优化,是算法竞赛中的经典题型。

二、解题思路

核心思路为“动态规划+完全背包问题”。每天将当前商品价格与次日差价视为“物品价值”,通过滚动计算次日可获得的“最大收益背包”,动态更新总金币数。关键在于将“连续两天的差价利润”转化为可重复选择的“背包物品”,利用dp[i](i金币时的最大收益)实现状态转移

三、解题步骤

1. 输入处理:读取天数T、商品数N、初始金币M及每日价格矩阵

2. 外层循环遍历T-1天(最后一天无法交易)。

3. 内层循环处理当日商品:计算差价profit,仅对正利润商品执行完全背包更新(避免无利操作)。

4. 状态转移方程:dp[j]=max(dp[j],dp[j-cost]+profit),实现“用剩余金币重复购买差价商品”的逻辑。

5. 每日结束后,将dp[M]累加到总金币M,滚动优化。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); // 优化输入效率
    
    int T, N, M;
    cin >> T >> N >> M; // 输入天数、商品数、初始金币
    
    vector<vector<int>> prices(T, vector<int>(N)); // 价格矩阵
    for (int i = 0; i < T; ++i) {
        for (int j = 0; j < N; ++j) {
            cin >> prices[i][j];
        }
    }
    
    // 每天处理时,计算当天到第二天的最大收益
    for (int day = 0; day < T - 1; ++day) {
        vector<int> dp(M + 1, 0); // dp[i]表示i金币能获得的最大收益
        
        for (int item = 0; item < N; ++item) {
            int cost = prices[day][item];
            int profit = prices[day + 1][item] - cost; // 次日差价
            
            if (profit <= 0) continue; // 无利可则跳过
            
            // 完全背包问题解法
            for (int j = cost; j <= M; ++j) { // 从成本开始累加
                dp[j] = max(dp[j], dp[j - cost] + profit); // 状态转移
            }
        }
        
        // 更新最大金币数
        M += dp[M];
    }
    
    cout << M << endl; // 输出最终金币
    return 0;
}

五、总结

该解法巧妙将“连续两天的利润”抽象为可重复选择的“背包物品”,通过动态规划规避了复杂的路径搜索。关键在于识别问题中的“资源可重复利用”特性,并应用完全背包模型简化计算。对算法竞赛中的资源分配类问题具有重要参考价值。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣5:中心扩散法 轻松破解最长回文子串

力扣5:中心扩散法 轻松破解最长回文子串

题目解读:在一个给定的字符串中,我们需要找到最长的回文子串。回文是指正读反读都相同的字符串,如"aba"、"abba"都是回文。这个问题看似简单,但要在字符串中...

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。