码迷,mamicode.com
首页 > 编程语言 > 详细

【读书笔记/复健向】算法竞赛入门经典训练指南1.1贪心部分

时间:2015-06-23 21:23:18      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

例题一(UVa11292)

基础贪心,没什么需要多讲的,直接放上代码。有一点要注意的是我第一遍写的时候竟然犯了两个错误。

错误点

  1. 将dragon、knight与i、j对应错误了,仔细一想人有先后对应的天性,下次设置i、j时还是老老实实根据输入顺序来,避免出错
  2. 第23行遗漏了(j<n)这个条件,使得在龙已经全被砍头的情况下却雇佣了剩余的骑士。

本题重点

砍龙头的时候设置两个指针,分别移动,使用频率挺高的一个小技巧,不难,但是挺重要的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm> 
 4 using namespace std;
 5 
 6 const int MAXN=20000;
 7 int dragon[MAXN];
 8 int knight[MAXN];
 9 
10 int main()
11 {
12     int n,m;
13     while (scanf("%d%d",&n,&m))
14     {
15         int sum=0;
16         if ((n==m) && (n==0)) break;
17         for (int i=0;i<n;i++) scanf("%d",&dragon[i]);
18         for (int i=0;i<m;i++) scanf("%d",&knight[i]);
19         sort(dragon,dragon+n);
20         sort(knight,knight+m);
21         int i=0,j=0;
22 
23         while ((i<m) && (j<n))
24         {
25             if (knight[i]>=dragon[j])
26             {
27                 j++;
28                 sum+=knight[i];
29             }
30             i++;
31         }
32         if (j<n) cout<<"Loowater is doomed!"<<endl;
33         else cout<<sum<<endl;
34     }
35     return 0;
36 }

 

 

例题二(UVa11729)

较基础贪心,关键是证明执行时间长的先交代,总时间最短这个命题以及在执行时间相同的情况下如何安排次序这个问题。当然事实证明执行时间相同的情况下,如何安排次序是无所谓的。书上已经讲得很清楚了,这里不进行过多阐述。(详见P4图解)注意的是书上的图(b)下方有误,应为B[Y]+B[X]+J[Y]。

 

对于书中标程的一些说明

  1. 书上用到了<vector>,我也不知道比赛的时候能不能用(哪个神犇来告诉我一下),也觉得没有必要用,写程序的时候就没有用到<vector>了。
  2. 这里有个非常重要的struct比较大小的简便写法,刚开始学C++要重点学习一下。其中Rec表示我们设置的记录。
    1 struct Rec
    2 {
    3     int b,j;
    4     bool operator < (const Rec& x) const
    5     {
    6         return j<x.j;
    7     }
    8 };
  3. 书中循环的判断条件中出现的scanf(“%d”,&n) == 1的含义即为输入的n为一个数字。因为scanf判断输入正确时返回值为数字,若非法则返回值为0,循环中    止。在这里其实可以不必用的,但在诸如:最后一位用字符表示中止循环条件时,非常好用。

 

错误点

  1. 第一遍的时候全然忘记sort是从小到大排序的了,于是耍了一个小聪明把return j<x.j中的小于号改为大于号即可,觉得自己超机智的时候发现树上就是这么干的。或者老老实实地把循环敲为for (int i=n-1;i>=0;i++)个人推荐后者,因为(个人实践表明)耍小聪明总是没有好下场的。

本题重点

对于贪心的证明是个重点,代码28-33行的小技巧在执行任务类的题目里非常常见,要重点牢记

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int MAXN=1000;
 6 int b[MAXN];
 7 int j[MAXN];
 8 
 9 struct task
10 {
11     int b,j;
12     bool operator < (const task& x) const
13     {
14         return j>x.j;//因为要从大到小排所以这里变动一下 
15     }
16 };
17 
18 int main()
19 {
20     int cases=0,n;
21     while (scanf("%d",&n))
22     {
23         cases++;
24         if (n==0) break;
25         task kase[MAXN];
26         for (int i=0;i<n;i++) scanf("%d%d",&kase[i].b,&kase[i].j);
27         sort(kase,kase+n);
28         int m=0,ans=0;
29         for (int i=0;i<n;i++)
30         {
31             m+=kase[i].b;
32             ans=max(ans,m+kase[i].j);
33         }
34         cout<<"Case "<<cases<<": "<<ans<<endl;
35     }
36     return 0;
37 }

 

 

TBC,预告会补充贪心的练习题和《挑战程序设计》上涉及贪心的习题。

【读书笔记/复健向】算法竞赛入门经典训练指南1.1贪心部分

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/4596148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!