Educational Codeforces Round 21 E. Selling Souvenirs 三分, 贪心
2017-07-21 22:43
537 查看
题目链接: E. Selling Souvenirs
题目大意
n件物品, 容量为m的背包, 每件物品有重量w, 价值c求能装下的最大价值
(1 ≤ n ≤ 105,1 ≤ m ≤ 3⋅105,1 ≤ wi ≤ 3,1 ≤ ci ≤ 109)
思路
乍一看是背包, 但除了重量只有三个取值, 其他值的范围都太大, 要从重量入手有三个重量,每次取某个重量的物品肯定是先取价格最高的,所以我们把三种重量的物品分开存,并按价值从大到小排序
然后枚举重量为3的物品的个数i(i∈[0,min(count[3],m/3)])
还剩下重量为2和1的物品,很明显,如果知道了重量为2的物品的数量,剩下的重量全部用重量为1的物品填充就好了。
并且,随着物品2的数量增多,总价值也增加,当达到某个值后,总价值开始下降,所以这里是一个先递增后递减的关系,可以用三分法求出最优解,总复杂度O(nlogn)
**注意, 三分的过程不能处理区间端点的值(极端情况下, 极值在区间端点取到, 也就是变成了单调函数), 所以要先特判两个端点的情况
代码
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5; typedef long long ll; int n, m, a, b; ll c[3][maxn]; ll sum[3][maxn]; int cnt[3]; ll cal(int n3, int n2) { return sum[2][n3] + sum[1][n2] + sum[0][min(cnt[0], m-n3*3-n2*2)]; } int main() { cin >> n >> m; for(int i=0; i<n; ++i) { scanf("%d%d", &a,&b); c[a-1][cnt[a-1]++] = b; } for(int i=0; i<3; ++i) sort(c[i], c[i]+cnt[i], greater<ll>()); for(int i=0; i<3; ++i) for(int j=1; j<=cnt[i]; ++j) sum[i][j] = sum[i][j-1] + c[i][j-1]; ll ans = 0; for(int i=0; i<=min(m/3, cnt[2]); ++i) { int l=0, r=min((m-i*3)/2, cnt[1]), lm, rm; ans = max(ans, max(cal(i, l), cal(i, r))); while(l<r-1) { lm = (l+r)>>1; rm = (lm+r)>>1; if(cal(i, lm) > cal(i, rm)) r = rm; else l = lm; } ans = max(ans, max(cal(i, l), cal(i, r))); } cout << ans << endl; return 0; }
相关文章推荐
- Educational Codeforces Round 21 E - Selling Souvenirs(三分or贪心背包)
- Educational Codeforces Round 21-E-贪心背包or
- Educational Codeforces Round 21 C. Tea Party 贪心
- Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)
- Educational Codeforces Round 21 Problem E(Codeforces 808E) - 动态规划 - 贪心
- Educational Codeforces Round 6 C. Pearls in a Row(贪心)
- Educational Codeforces Round 36 (Rated for Div. 2)C. Permute Digits(贪心)
- Educational Codeforces Round 21 C. Tea Party
- Educational Codeforces Round 21-G
- Educational Codeforces Round 12 C. Simple Strings 贪心
- Educational Codeforces Round 36 B. Browser 简单贪心
- Educational Codeforces Round 25 D Suitable Replacement 贪心
- Educational Codeforces Round 6-C. Pearls in a Row(贪心)
- Educational Codeforces Round 21 C. Tea Party
- Educational Codeforces Round 21 B.Average Sleep Time 前缀和,双指针
- Educational Codeforces Round 2 C. Make Palindrome 贪心
- Educational Codeforces Round 24 F. Level Generation(三分)
- Educational Codeforces Round 5(B)贪心
- Educational Codeforces Round 3 D.Gadgets for dollars and pounds(贪心&&二分)
- codeforces Educational Codeforces Round 21 A - Lucky Year