1 条题解
-
7
提供一个好想,但时间比较劣的写法。
设第 家店买家电、家具、装饰的价格分别为 。
总花费可以写成:
$$\sum_{i=1}^{n} c_i + \sum_{\text{买家电的店}}(a_i - c_i) + \sum_{\text{买家具的店}}(b_i - c_i)$$也就是说,先假设所有店都买装饰,花费为 ,然后把其中 家店改成买家电,额外花费 ;把其中 家店改成买家具,额外花费 。
于是问题变成:从 家店中选出 家买家电、 家买家具,使得额外花费之和最小。
如果两家店 ,其中 买家电, 买家具,那么交换它们的选择后花费变化为:
$$(a_j - c_j) + (b_i - c_i) - (a_i - c_i) - (b_j - c_j) = (a_j + b_i) - (a_i + b_j)$$如果 ,即 ,那么交换后花费更小。所以最优解中,买家电的店一定满足 不大于买家具的店。
因此,将所有店按 从小到大排序后,一定存在一个分界点 ,使得前 家店中选 家买家电,后 家店中选 家买家具。
所以,我们可以枚举 。设 ~ 中 个最小的 的和为 ,和 ~ 中 个最小的 的和为 ,所有基础花费(装修)的和为 。对于每个 ,它的答案是 ,最后对每个答案取 即可。
时间复杂度: ,最大 ,实际常数较大,可以过。
参考代码(仅展示关键部分)
ll ans=1e18; for(int p=a;p<=n-b;p++){ vector<ll> l,r; for(int i=1;i<=p;i++) l.push_back(buy[i].a-buy[i].c); for(int i=p+1;i<=n;i++) r.push_back(buy[i].b-buy[i].c); sort(l.begin(),l.end()); sort(r.begin(),r.end()); ll suma=0,sumb=0; for(int i=0;i<a;i++) suma+=l[i]; for(int i=0;i<b;i++) sumb+=r[i]; ans=min(ans,suma+sumb+sumc); }
信息
- ID
- 2740
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 34
- 已通过
- 11
- 上传者