POJ2376
给你若干个线段的开始点和结束点,你需要的是把这些线段覆盖起来,使其能完整地盖住一段区间
问题是贪心,首先做的是排除那些无用的线段(起始点相同但是长度较短),然后维护一个临时的上界,注意只有当现在线段的下一个线段不能覆盖住整个区间的时候才增加下一个。
1 #pragma GCC optimize(3) 2 #include <time.h> 3 #include <algorithm> 4 #include <bitset> 5 #include <cctype> 6 #include <cmath> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <deque> 11 #include <functional> 12 #include <iostream> 13 #include <map> 14 #include <queue> 15 #include <set> 16 #include <sstream> 17 #include <stack> 18 #include <string> 19 #include <typeinfo> 20 #include <utility> 21 #include <vector> 22 using namespace std; 23 const double EPS = 1e-9; 24 const int INF = 2147483647; 25 const long long LLINF = 9223372036854775807; 26 const double PI = acos(-1.0); 27 28 inline int READ() { 29 char ch; 30 while ((ch = getchar()) < 48 || 57 < ch) 31 ; 32 int ans = ch - 48; 33 while (48 <= (ch = getchar()) && ch <= 57) 34 ans = (ans << 3) + (ans << 1) + ch - 48; 35 return ans; 36 } 37 38 #define REP(i, a, b) for (int i = (a); i <= (b); i++) 39 #define PER(i, a, b) for (int i = (a); i >= (b); i--) 40 #define MP(x, y) make_pair(x, y) 43 #define PB(x) push_back(x) 44 #define SET(a) memset(a, -1, sizeof(a)) 45 #define CLR(a) memset(a, 0, sizeof(a)) 46 #define MEM(a, x) memset(a, x, sizeof(a)) 47 #define ALL(x) begin(x), end(x) 48 #define LL long long 49 #define Lson (index * 2) 50 #define Rson (index * 2 + 1) 51 #define pii pair<int, int> 52 #define pll pair<LL, LL> 53 #define MOD ((int)1000000007) 54 #define MAXN 1000 + 5 55 ///**********************************START*********************************/// 56 57 int N, T, cnt; 58 struct cow { 59 int l, r; 60 cow(int x, int y) : l(x), r(y) {} 61 bool operator<(const cow &rhs) const { 62 return l == rhs.l ? r > rhs.r : l < rhs.l; 63 } 64 }; 65 set<cow> s; 66 map<int, int> mp; 67 68 int main() { 69 // freopen("input.txt", "r", stdin); 70 N = READ(), T = READ(); 71 pii a; 72 REP(i, 1, N) { 73 a.first = READ(), a.second = READ(); 74 if (mp[a.first] < a.second) mp[a.first] = a.second; 75 } 76 /* cout << endl; 77 for (auto i : mp) cout << i.first << " " << i.second << endl; */ 78 int up = 0, tmp = 0, flag = 0; 79 for (map<int, int>::iterator i = mp.begin(); i != mp.end(); i++) { 80 int l = (*i).first, r = (*i).second; 81 if (l <= up + 1) { 82 if (r > tmp) { 83 tmp = r; 84 flag = 1; 85 } 86 map<int, int>::iterator it = i; 87 it++; 88 if ((it == mp.end() && up < T && tmp >= T) || 89 ((*it).first > up + 1 && flag)) { 90 up = tmp; 91 cnt++; 92 flag = 0; 93 } 94 } 95 } 96 if (up >= T) 97 printf("%d", cnt); 98 else 99 printf("-1"); 100 return 0; 101 }
POJ2393
题意:每周可以生产牛奶,每周生产的价格为Ci,每周需要上交的牛奶量Yi,你可以选择本周生产牛奶,也可选择提前几周生产出存储在仓库中(仓库无限大,而且保质期不考虑),每一周存仓库牛奶需要花费S元,让你求出所有周的需求量上交的最少花费。
解:核心是找到当前这一周前面最近的且价格最低的那一周,直接找会N2超时,转换思路,从前到后遍历,将每一周的价格修改为从前一周保存还是从当前周购买(将最优的策略传递下来),这样子你面临的就是已有的当前可以选择的最优解和现在的最优解。
1 int N, S; 2 int c[MAXN], y[MAXN]; 3 LL ans; 4 5 int main() { 6 // READ_FROM_FILE; 7 N = READ(), S = READ(); 8 REP(i, 1, N) c[i] = READ(), y[i] = READ(); 9 REP(i, 2, N) c[i] = min(c[i - 1] + S, c[i]); 10 REP(i, 1, N) ans += c[i] * y[i]; 11 printf("%lld", ans); 12 return 0; 13 }
POJ3040
题意:有N种硬币,每个有B个,你每天需要给某人价值为C的硬币,问怎样安排可以让给的时间最长
解法:贪心策略,先拿大的,然后用小的补齐,这个实现的时候挺有技巧的,注意代码
1 struct COIN { 2 int val, num; 3 bool operator<(const COIN& rhs) const { return val > rhs.val; } 4 } a[MAXN]; 5 int N, c; 6 int main() { 7 // freopen("input.txt", "r", stdin); 8 scanf("%d%d", &N, &c); 9 for (int i = 1; i <= N; i++) scanf("%d%d", &a[i].val, &a[i].num); 10 sort(a + 1, a + 1 + N); 11 int ans = 0, pos; 12 for (int i = 1; i <= N; i++) { 13 if (a[i].val >= c) { 14 ans += a[i].val / c * a[i].num; 15 } else { 16 pos = i; 17 break; 18 } 19 } 20 while (1) { 21 int now = 0; 22 for (int i = pos; i <= N; i++) { 23 while (a[i].num && a[i].val + now <= c) { 24 now += a[i].val; 25 a[i].num--; 26 } 27 } 28 for (int i = N; i >= pos; i--) { 29 while (a[i].num && now < c) { 30 now += a[i].val; 31 a[i].num--; 32 } 33 } 34 if (now < c) break; 35 ans++; 36 } 37 printf("%d ", ans); 38 return 0; 39 }