补题 946E. Money Buys Happiness dp
作者:
多米尼克領主的致意
,
2024-05-21 15:53:30
,
所有人可见
,
阅读 3
思路来自 幻想家协会会长
1.f定义为 当前幸福值为j的最大剩余钱数(因为题目内所有测试样例的hi和 <= 1e5)
2.在 i/th月赚到的钱只能在之后的 j/th月( j>i )花掉。
为了达成这一条件 每次工资在循环里通过fj += x发放 避免工资预支
3. 35行转移方程f[j] = max(f[j], f[j - v[i]] - c[i]) 中表示从小幸福值j - v[i]支付了c[i]元 转移到当前幸福值
判断条件1为 余额足够f[j - v[i]] >= c[i]
判断条件2为 当前枚举的幸福值大于当前月数的幸福值,因为幸福值不能为负数
code:
#include <bits/stdc++.h>
using namespace std;
const int N = 60, M = 1e5 + 10;
int t;
int c[N], v[N];
int f[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> t;//f为能够达成当前幸福值所剩余的最大金钱
while(t--){
int m, x;
cin >> m >> x;
int mx = 0;
for(int i = 1;i <= m;i++){
cin >> c[i] >> v[i];
mx += v[i];
}
memset(f, -0x3f, sizeof f);
// cout << f[0] << endl;
f[0] = 0;
for(int i = 1;i <= m;i++){
for(int j = mx; j >= 0;j--){
if(j >= v[i] && f[j - v[i]] >= c[i])
f[j] = max(f[j], f[j - v[i]] - c[i]);
f[j] += x;
}
}
int ans;
for(int i = 1;i <= mx;i++){
if(f[i] >= 0){
ans = i;
}
}
cout << ans << endl;
}
return 0;
}