专栏文章
题解:P5662 [CSP-J2019] 纪念品
P5662题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miobkp1c
- 此快照首次捕获于
- 2025/12/02 16:32 3 个月前
- 此快照最后确认于
- 2025/12/02 16:32 3 个月前
P5662 [CSP-J2019] 纪念品题解
前言
虽然这道题的题解提交通道已经关闭,但是这道题实在是值得写一篇题解。我看完题目以后一脸懵b,听完老师的讲解才知道如此简单。
思路
完全背包。既然是背包,就要找到质量 和价值 。对于本题, 表示纪念品的价格。 每天都会变,因此我们将 扩大到2维,即 表示第 天第 件纪念品的价格,也就相当于题目中所给的 数组。问题来了,什么表示 ?这就需要我们将问题简化:假设第 天买完以后第 天立刻卖出,即使第 天卖出赚的更多,也可以选择第 天再买,第 天卖出。于是,我们定义 ,表示第 天买入第 件纪念品后第 天卖出的收益。这样,完全背包外面再套一层循环表示天数,每天收益加一起,本题结束。
状态转移方程
代码
CPP#include <bits/stdc++.h>
using namespace std;
//注意dp数组不是开到m,因为总钱数每天都会变
//题面: 对于100%的数据,小伟手上的金币数不可能超过10^4
int w[110][110],dp[10010];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t,n,m;
cin>>t>>n>>m;
for (int i=1;i<=t;i++){
for (int j=1;j<=n;j++){
cin>>w[i][j];
}
}
//从第1天到第t-1天进行交易,第t天只负责卖
for (int i=1;i<t;i++){
memset(dp,0,sizeof dp);
//完全背包,n件物品,m枚金币
for (int j=1;j<=n;j++){
for (int k=w[i][j];k<=m;k++){
//dp[k]在第i天买入第j件物品后的最大总钱数
//dp[k-w[i][j]]在第i天买入第j件物品前的最大总钱数
//w[i+1][j]-w[i][j]在第i天买入第j件物品后在第i+1天卖出的最大收益
dp[k]=max(dp[k],dp[k-w[i][j]]+(w[i+1][j]-w[i][j]));
}
}
//今天的总钱数再加上明天的收益就是明天的起始钱数
m+=dp[m];
}
cout<<m;
return 0;
}
双倍经验
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...