其实是贪心,开始没看清题意,把 a b 两种披萨分开进行背包。。。。
贪心的话就是,先选取 a b 中最有幸福值的那个,然后分别储存差值,
最后看分别选取的 a b 两种是不是最少选取的披萨数,不是的话进行调节,看看把 部分a换成b 还是反过来减少的幸福值更少
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 7;
int n, m, s;
ll v1, v2, ans, sum, sum1, sum2;
vector<pair<ll,int> > vec1, vec2;
void init() {
scanf("%d %d", &n, &m);
ans = 0; sum = sum1 = sum2 = 0;
for(int i = 0; i < n; ++i) {
scanf("%d %lld %lld", &s, &v1, &v2);
sum += s;
if(v1 >= v2) {
ans += (s*v1); sum1 += s;
vec1.push_back(make_pair(v1-v2, s));
}
else if(v1 < v2) {
ans += (s*v2); sum2 += s;
vec2.push_back(make_pair(v2-v1, s));
}
}
sort(vec1.begin(), vec1.end());
sort(vec2.begin(), vec2.end());
}
void get() {
int t1 = sum1 % m, t2 = sum2 % m;
ll res1 = 0, res2 = 0;
for(int i = 0; i < vec1.size() && t1; ++i) {
res1 += (min(t1, vec1[i].second) * vec1[i].first);
t1 -= min(t1, vec1[i].second);
}
for(int i = 0; i < vec2.size() && t2; ++i) {
res2 += (min(t2, vec2[i].second) * vec2[i].first);
t2 -= min(t2, vec2[i].second);
}
ans -= min(res1, res2);
}
void solve() {
ll t = (sum % m == 0 ? 0 : 1);
ll t1 = (sum1 % m == 0 ? 0 : 1), t2 = (sum2 % m == 0 ? 0 : 1);
if(sum1/m + sum2/m + t1 + t2 > sum/m + t) {
get();
printf("%lld\n", ans);
}
else {
printf("%lld\n", ans);
}
}
int main() {
init();
solve();
return 0;
}