题目链接:http://codeforces.com/problemset/problem/441/B
题目意思:有 n 棵fruit trees,每课水果树有两个参数描述:水果成熟的时间和这棵树上水果的数量。已知Valera 每天最多可以采摘 v 个水果,而每棵fruit tree能被采摘水果的天数只能在它水果成熟的那一日(ai)和后一日(ai+1),超过这两日就不能采摘这棵树的水果了。问如何操作可以使最后采摘到的水果数最多。
实不相瞒,做这条题做得蛮久的,可能与忙于考试没怎么做题有关.....开始时候还想得比较复杂......
由于可能有多棵fruit trees成熟的天数是一样的,那么可以将这些成熟的日子相同的fruit tree归为一类。即 1 5; 1 3; 1 6 ——> 1 14,代表第1天~第2天能采摘的水果数是55个。此时另一个问题出现了,如果对于 2 2;2 4; 2 5(第2天~第3天能够采摘),而Valera 每天能采摘的水果数是v = 8,那么结合上面的数据来考虑,就会发觉,当第二天的时候,他需要把剩余的第一天成熟的水果:6个 + 第二天成熟的水果:2个 都采摘才是当天能采摘水果数的最优方案。所以前一天的水果数也需要考虑。也就是类似当达到第二天的时候,要看看第一天是否有剩余未采摘的水果。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 3000; 8 int tree[maxn]; 9 10 int main() 11 { 12 int n, v; 13 while (scanf("%d%d", &n, &v) != EOF) 14 { 15 int ripen_day, num_of_fruit, max_day = 0; 16 memset(tree, 0, sizeof(tree)); 17 for (int i = 0; i < n; i++) 18 { 19 scanf("%d%d", &ripen_day, &num_of_fruit); 20 tree[ripen_day] += num_of_fruit; // 第ripen_day中最多能采摘到的水果数 21 max_day = max(max_day, ripen_day); // 求出所有树中水果最迟成熟的日子 22 } 23 24 int ans = 0; 25 for (int i = 1; i <= max_day+1; i++) // max_day+1表示那棵水果最迟成熟的日子能偶在max_day和max_day+1中采摘 26 { 27 int tv = v; // 每天最多能够采摘的水果数量 28 if (tree[i-1]) // 前一天是否有剩余水果未采摘 29 { 30 if (tree[i-1] < tv) 31 { 32 ans += tree[i-1]; 33 tv -= tree[i-1]; // 第i天最多能采摘tv个水果 34 } 35 else 36 { 37 tree[i-1] -= tv; 38 ans += tv; 39 tv = 0; 40 } 41 } 42 if (tree[i] < tv) 43 { 44 ans += tree[i]; 45 tree[i] = 0; 46 } 47 else 48 { 49 ans += tv; 50 tree[i] -= tv; 51 } 52 } 53 printf("%d ", ans); 54 } 55 return 0; 56 }