Codeforces Educational Codeforces Round 3 D. Gadgets for dollars and pounds(二分 + 贪心)
2015-12-20 01:52
399 查看
题意:
给定N≤2×105天的dollar和pound的兑换率,总共有M≤105个玩具售卖,分为1和2两种
要买k≤M个,现有s≤109钱,问最快哪天可以买到,一天可以买多个
分析:
一天可以买多个,那显然一次性买好最好
今天可以买到,明天也能买到,显然的单调性,维护一个前缀兑换率的min,记录下取到最小值的那一天,二分天数
两种玩具分开维护个前缀和,只有两种,枚举其中一种的个数,另一个可以算出来,判断是否可以买到
问题解决,不算排序,复杂度O(klogn)
代码:
给定N≤2×105天的dollar和pound的兑换率,总共有M≤105个玩具售卖,分为1和2两种
要买k≤M个,现有s≤109钱,问最快哪天可以买到,一天可以买多个
分析:
一天可以买多个,那显然一次性买好最好
今天可以买到,明天也能买到,显然的单调性,维护一个前缀兑换率的min,记录下取到最小值的那一天,二分天数
两种玩具分开维护个前缀和,只有两种,枚举其中一种的个数,另一个可以算出来,判断是否可以买到
问题解决,不算排序,复杂度O(klogn)
代码:
// // Created by TaoSama on 2015-12-20 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 2e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; typedef long long LL; typedef pair<LL, int> P; int n, m, k, s; P a , b ; P one , two ; int cnt1, cnt2, ans, ans1, ans2; bool check(int x) { LL dollar = a[x].first, pound = b[x].first; for(int i = 0; i <= k && i <= cnt1; ++i) { if(k - i > cnt2) continue; LL sum = one[i].first * dollar + two[k - i].first * pound; if(sum <= s) { ans = i; ans1 = a[x].second; ans2 = b[x].second; return true; } } return false; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d%d%d", &n, &m, &k, &s) == 4) { a[0].first = b[0].first = INF; for(int i = 1; i <= n; ++i) { scanf("%I64d", &a[i].first); a[i].second = a[i - 1].second; if(a[i].first < a[i - 1].first) a[i].second = i; else a[i].first = a[i - 1].first; } for(int i = 1; i <= n; ++i) { scanf("%I64d", &b[i].first); b[i].second = b[i - 1].second; if(b[i].first < b[i - 1].first) b[i].second = i; else b[i].first = b[i - 1].first; } cnt1 = cnt2 = 0; for(int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); if(x == 1) one[++cnt1] = P(y, i); else two[++cnt2] = P(y, i); } sort(one + 1, one + 1 + cnt1); sort(two + 1, two + 1 + cnt2); for(int i = 1; i <= cnt1; ++i) one[i].first += one[i - 1].first; for(int i = 1; i <= cnt2; ++i) two[i].first += two[i - 1].first; int l = 1, r = n; while(l <= r) { int m = l + r >> 1; if(check(m)) r = m - 1; else l = m + 1; } if(l == n + 1) puts("-1"); else { printf("%d\n", l); for(int i = 1; i <= ans; ++i) printf("%d %d\n", one[i].second, ans1); for(int i = 1; i <= k - ans; ++i) printf("%d %d\n", two[i].second, ans2); } } return 0; }
相关文章推荐
- 快速排序里的学问:从猜数字开始
- 1.一些 贪心算法 的简单思维题:
- 贪心算法——字典序最小问题
- 贪心算法——区间调度问题
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- Jump Game I,II 贪心
- Search Insert Position,Search for a Range,Pow(x, n),Sqrt(x)
- Find Minimum in Rotated Sorted Array II
- Wildcard Matching
- 贪心法实现无向图的划分 代码
- 贪心题目循环和控制台折行
- HDOJ 1009
- [LeetCode] Sqrt(x)
- [LeetCode] Pow(x, n)
- [LeetCode] Search Insert Position
- [LeetCode] Search for a Range
- [LeetCode] Search in Rotated Sorted Array
- 【解题报告】【USACO】酸奶工厂
- 【解题报告】【】交谊舞
- POJ 1328