(今天的学长开场都没怎么具体讲贪心的概念,直接开始讲题了,我就自己总结一点吧)
贪心的思路,简单地说就是对于一个问题,对于它分支出的每一个局部小问题都选择最优解,从而得到整体最优解。贪心应该更被认为是一种解题策略而非算法。
使用贪心策略,需要问题的最优解包含子问题的最优解,即得到子问题最优解便得到了整体的最优解(具有最优子结构),并且某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响(无后效性),在具体编写时往往与结构体排序相搭配。
在实际解题过程中,若已经分析得出一道题可用贪心求解,那么编写代码的过程可能相对较容易。往往更复杂的是对问题的解读和分析,典型题目如NOIP 2012 国王游戏。真正面对此类题型时,我在此套用一句高中期间集训老师的话:“大胆猜想,合理假设” (简单点说就是莽)
例题
HDU 2037 今年暑假不AC
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct node
{
int a,b;
}N;
N num[110];
int cmp(const void *a,const void *b)
{
N *q=(N *)a;
N *p=(N *)b;
if(q->b!=p->b)return q->b-p->b;
return q->a-p->a;
}
int main()
{
int n;
scanf("%d",&n);
while(n!=0)
{
for(int i=0;i<n;i++)scanf("%d%d",&num[i].a,&num[i].b);
qsort(num,n,sizeof(num[0]),cmp);
int ti=0,ans=0;
for(int i=0;i<n;i++)
{
if(num[i].a>=ti)
{
ans++;
ti=num[i].b;
}
}
printf("%d\n",ans);
scanf("%d",&n);
}
return 0;
}
CodeForces 1159B Expansion coefficient of the array
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#define oo 2147483647
using namespace std;
typedef struct node
{
int w;
int id;
}N;
N num[300010];
int cmp(const void *a,const void *b)
{
N *q=(N *)a;
N *p=(N *)b;
return p->w-q->w;
}
int main()
{
int n,maxid,minid,ans=oo;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
num[i].id=i;
scanf("%d",&num[i].w);
}
qsort(num,n,sizeof(num[0]),cmp);
minid=num[0].id;
maxid=num[0].id;
for(int i=1;i<n;i++)
{
if(num[i].w/abs(minid-num[i].id)<ans)ans=num[i].w/abs(minid-num[i].id);
if(num[i].w/abs(maxid-num[i].id)<ans)ans=num[i].w/abs(maxid-num[i].id);
if(num[i].id>maxid)maxid=num[i].id;
if(num[i].id<minid)minid=num[i].id;
}
printf("%d\n",ans);
return 0;
}