算法概述:贪心顾名思义,每一步决策都选择目前的最优解,合起来可以产生全局最优解
时间复杂度:取决于代码
算法特点:难以构造模型,代码较简单,使用的时候需要严谨的数学证明(证不出来的就举例子证明)
以排队接水为例
题目链接
信息学奥赛一本通(C++版)在线评测系统
分析:因为每个人等待接水的时间由他之前的人接水时长之和,所以,越靠前接水的人,接水所需的时长,对总时长的影响就越大。若使总时长最短,则需越靠前接水的人接水时长越短,只需让排队顺序按照接水时长升序排列即可。
确定思路,开始撸码
#include#include #include using namespace std; const int N = 1010; double ti; int n; struct peo { double t; int id; }a[N]; bool cmp (peo a,peo b) { return a.t < b.t; } int main () { cin >> n; for (int i = 1;i <= n;i++) { cin >> a[i].t; a[i].id = i; } sort(a + 1,a + 1 + n,cmp); cout << a[1].id << " "; for (int i = 2;i <= n;i++) { cout << a[i].id << " "; ti += a[i - 1].t * (n - i + 1); } cout << endl; ti /= n; printf ("%0.2lfn",ti); return 0; }
题目链接
信息学奥赛一本通(C++版)在线评测系统
分析:需要尽可能少的导弹拦截系统,所以要让一个导弹拦截系统拦截的导弹尽可能的多,让一个导弹拦截系统从开始启用后,向后面遍历,只要遇到一个没有被拦截的导弹且满足拦截条件的导弹,就将它拦截并更新高度,一直到数组末尾。重复n次这个过程,知道所有导弹都被拦截。
确定思路,开始撸码
#includeusing namespace std; const int N = 1050; int a[N],n,k,cnt; int main () { while (cin >> a[++n]); for (int i = 1;i <= n;i++) { if (a[i] != -1) { cnt = a[i]; k++; for (int z = i + 1;z <= n;z++) { if(a[z] != -1 && a[z] <= cnt) { cnt = a[z]; a[z] = -1; } } } } cout << k << endl; return 0; }
题目链接
信息学奥赛一本通(C++版)在线评测系统
分析:要安排尽可能多的活动,每一个活动占用的时间区间要尽可能短,每一个活动的结束时间要尽可能靠前,所以,将活动的结束时间按照升序排列,从第一项开始,依次判断活动的开始时间是否冲突,如果不冲突,那么就可以选择这项活动,同时更新结尾时间。
确定思路,开始撸码
#include#include using namespace std; const int N = 1010; int n,res = 1; struct node { int s,e; }a[N]; bool cmp (node a,node b ) { return a.e < b.e; } int main () { cin >> n; for (int i = 1;i <= n;i++) { cin >> a[i].s >> a[i].e; } sort (a + 1,a + 1 + n,cmp); int se = a[1].e; for (int i = 2;i <= n;i++) { if (a[i].s >= se) { res++; se = a[i].e; } } cout << res << endl; return 0; }



