codeforces 436A. Feed with Candy 解题报告

题目链接:http://codeforces.com/contest/436/problem/A

题目意思:给出 n 颗只有两种类型:fruit 和 caramel的candies,这些candies是挂在屋子上的,对于第 i 颗candy,它离地面为 hi 厘米,质量为 mi;有只叫Om Nom的怪兽想尽可能地把这些candy吃光,它初始的时候只能跳 x 的高度,如果有某颗或者一些candy离地面的距离 <= x,就代表Om Nom可以吃掉,吃掉之后它下一次可以跳的高度会变成 x + mi(mi代表某颗低于 x 厘米的candy 的质量),也就是增加 mi。

  以下注释部分大家可以忽略,谨纪念一个做题年轻的我回首不堪的做题往事......

  /******************************************

    总的来说,就是经历了一番纠缠!!!不过后来有种终于看清楚问题本质的感觉,真是超级美好。就像坐海盗船~~咯!!呵呵.....

    是这样的,每种candy有两个数限制:h 和 m,我很容易地想到要对 h 从小到大排序,如果 h 相等的话,就对m从大到小排序,因为怪兽要跳到上去的条件就是这个怪兽所能跳的高度 >= 这颗candy的高度,排完之后,问题就转移到要选择哪种类型的candy了。我竟然直接根据两种类型的第一颗来讨论,当中还有n 多的重复代码(当时是这样想的,先要保证能解决,有时间才开始优化),于是就,死就死了,果不其然- -.....第一次比赛写那么长的代码...第二次修改还是没有走出这个坑,还自鸣得意地把一些重复情况合在一起= =;紧接着就是傻到竟然把一些 h 相同的candy过滤掉,剩下那颗m最大的candy,把m加到当前的x上!哇~~~我的天啊= =。 200+ 的代码,还过不了,看来真的不是状态啊

    *********************************************/

   就这样,一直过不了pretest 8,后来才发现大数据啊!于是看人家过了的数据,原来对于这类的数据过不了:

    5 2

  0 2 4

  1 3 1

  0 8 3

  0 20 10

  1  5  5

    注意 0 2 4 和 1 3 1 这两行数据,按我的做法,1 3 1 比 1 5 5 排得前,也就是先选择1 3 1 而不选择 1 5 5,这样的话,选了1 3 1 之后这只怪兽就再也不能吃到candy了!只能吃到2颗,而答案应该是4颗。所以解决这个问题的关键就是:对于小于当前x(x = x + mi 或者初始的 x)的那些candy,选择 m 最大的那颗先吃。数据量不大,2000而已,2s跑2000 * 2000,绰绰有余了。

      出题分类是模拟,本人觉得有点像贪心。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 2000 + 10;
 8 int t[maxn], h[maxn], m[maxn];
 9 bool used[maxn];
10 
11 int main()
12 {
13     int n, x;
14     while (scanf("%d%d", &n, &x) != EOF)
15     {
16         for (int i = 0; i < n; i++)
17             scanf("%d%d%d", &t[i], &h[i], &m[i]);
18         int ans = 0;
19         for (int i = 0; i < 2 ; i++)  // 看从哪种糖果开头吃比较好
20         {
21             memset(used, false, sizeof(used));
22             int curx = x;
23             int curtype = i;
24             int curid = 0;
25             int curans = 0;
26             while (true)
27             {
28                 int curm = -1;
29                 for (int j = 0; j < n; j++)
30                 {
31                     if (!used[j] && t[j] == curtype && curx >= h[j] && curm <= m[j])
32                     {
33                         curm = m[j];   // 在高度 < curm的前提下,找出最大的m
34                         curid = j;     
35                     }
36                 }
37                 if (curm == -1)  // 已经找不到比curx 要 低的candy就退出
38                     break;
39                 used[curid] = true;  // 标记该糖果已吃
40                 curans++;         // 累计糖果数
41                 curx += curm;     // 更新之后能跳的高度
42                 curtype ^= 1;    // 控制糖果类型
43             }
44             ans = max(ans, curans);
45         }
46         printf("%d
", ans);
47     }
48     return 0;
49 }
原文地址:https://www.cnblogs.com/windysai/p/3788668.html