分析:
需要让所有x大于y的对应的z的总数大于z总共的数量的一半,找最小需要转化的数量,那么可以转化为01背包问题,z作为体积,每组的x和y都可以计算出一个值表示需不需要转化,作为背包价值,如果x大于y那么一定价值是0,否则至少需要(y - x) / 2 + 1数量转化,那么就转化成了背包dp,然后因为只要大于等于z总数的一半都可以符合,所以最后对满足的所有情况取最小值。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<ll> x(n + 1), y(n + 1), z(n + 1);
ll m = 0;
for(int i = 1; i <= n; i ++) {
cin >> x[i] >> y[i] >> z[i];
m += z[i];
}
vector<ll> f(m + 1, 1e17);
f[0] = 0;
for(int i = 1; i <= n; i ++) {
ll w = 0;
if(y[i] > x[i]) w = (y[i] - x[i]) / 2 + 1;
for(int j = m; j >= z[i]; j --) {
f[j] = min(f[j], f[j - z[i]] + w);
}
}
ll ans = 1e17;
for(int i = m / 2 + 1; i <= m; i ++) ans = min(ans, f[i]);
cout << ans << '\n';
}