feat: 添加P8903题解实现动态规划解法

实现了一个动态规划解决方案来计算最大收益,处理两种不同成本的物品选择。通过预处理前后缀最大值来优化计算效率。
This commit is contained in:
Zengtudor 2025-10-09 22:24:44 +08:00
parent 056863889b
commit 385380934e

87
src/10/9/P8903.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
using ll = int64_t;
const ll maxn = 2005;
struct C {
ll p, c, x;
bool operator<(const C &other) const {
return x < other.x;
}
} c[maxn];
ll n, a, b;
ll dpb[maxn][maxn], dpa[maxn][maxn];
ll mxb[maxn][maxn], mxa[maxn][maxn];
int main() {
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> a >> b;
for (ll i = 1; i <= n; i++) {
std::cin >> c[i].p >> c[i].c >> c[i].x;
}
std::sort(c + 1, c + 1 + n);
for (ll i = 1; i <= n; i++) {
for (ll j = 0; j <= b; j++) {
dpb[i][j] = dpb[i - 1][j];
if (j >= c[i].c * c[i].x) {
dpb[i][j] = std::max(dpb[i][j], dpb[i - 1][j - c[i].c * c[i].x] + c[i].p);
}
}
}
for (ll i = 1; i <= n; i++) {
for (ll j = 0; j <= b; j++) {
if (j > 0) {
mxb[i][j] = std::max(mxb[i][j - 1], dpb[i][j]);
} else {
mxb[i][j] = dpb[i][j];
}
}
}
for (ll i = n; i >= 1; i--) {
for (ll j = 0; j <= a; j++) {
dpa[i][j] = dpa[i + 1][j];
if (j >= c[i].c) {
dpa[i][j] = std::max(dpa[i][j], dpa[i + 1][j - c[i].c] + c[i].p);
}
}
}
for (ll i = n; i >= 1; i--) {
for (ll j = 0; j <= a; j++) {
if (j > 0) {
mxa[i][j] = std::max(mxa[i][j - 1], dpa[i][j]);
} else {
mxa[i][j] = dpa[i][j];
}
}
}
ll ans = 0;
ans = std::max(ans, mxb[n][b]);
ans = std::max(ans, mxa[1][a]);
for (ll i = 1; i <= n; i++) {
for (ll j = 0; j <= c[i].c; j++) {
ll mcost = c[i].c - j;
ll iccost = j * c[i].x;
if (mcost <= a && iccost <= b) {
ll pre = (i > 1) ? mxb[i - 1][b - iccost] : 0;
ll suff = (i < n) ? mxa[i + 1][a - mcost] : 0;
ans = std::max(ans, pre + c[i].p + suff);
}
}
}
std::cout << ans << "\n";
}