T1:垃圾游戏3
本题难度中等,一道稍有变化的01背包题。一般的01背包是考虑每个物品取和不取,本题是考虑每个物品带走(相当于取)还是分解(相当于不取),如果分解,也会贡献相应价值
记 dp[i][j]
表示前 个物品中选总重量不超过 的物品能得到的最大金币
转移:
- 分解:
- 装走:
是两者最大值
最终的答案是
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; int dp[1005][10005]; inline void chmax(int& x, int y) { if (x < y) x = y; } int main() { int n, m; cin >> n >> m; rep(i, n) { int w, v, c; cin >> w >> v >> c; for (int j = 0; j <= m; ++j) { int now = 0; chmax(now, dp[i-1][j]+c); if (j >= w) chmax(now, dp[i-1][j-w]+v); dp[i][j] = now; } } cout << dp[n][m] << '\n'; return 0; }
T2:飞盘队2
本题难度较大,一道计算方案数的01背包问题。如果以总能力值作为背包大小,只能得到 分。需要以能力值除以 余数作为 数组的第二维,并且建两个数组分别记最大总能力值和达成最大能力的方案数,仔细讨论状态转移,才能得到满分。
做法1:
记 dp[i][j]
表示从前 头牛中取总和为 的方案数
转移:
不取:dp[i][j] = dp[i-1][j]
取:dp[i][j] += dp[i-1][j-Ri] (j >= Ri)
初值:,其他
答案:找到使得 且 是 的倍数的最大的 ,答案是 和
但注意到 为 , 就是 了,而 就是 ,时间肯定要炸
做法2:
用 dp[i][j]
记录前 头牛中取若干头使总和除以 余 时能得到的最大总和
用 f[i][j]
记录得到最大和的方法数
初值:, 其他 ;,其他
转移:
不取:
取:
若 :
若 :
若 :
答案: 和
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; using ll = long long; int a[205]; int dp[205][1005]; ll f[205][1005]; inline void chmax(int& x, int y) { if (x < y) x = y; } int main() { int n, F; cin >> n >> F; memset(dp, 0xcf, sizeof dp); dp[0][0] = 0; f[0][0] = 1; rep(i, n) { int r; cin >> r; for (int j = 0; j < F; ++j) { int t1 = dp[i-1][j]; int nj = ((j-r)%F+F)%F; int t2 = dp[i-1][nj]+r; dp[i][j] = max(t1, t2); if (t1 > t2) f[i][j] = f[i-1][j]; else if (t1 < t2) f[i][j] = f[i-1][nj]; else f[i][j] = f[i-1][j] + f[i-1][nj]; } } cout << dp[n][0] << '\n' << f[n][0] << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现