贪心算法的本质是将复杂的问题简化为多个小问题,是某种意义上的局部最优解。
贪心算法要满足三个条件:
- 判断问题是否可以被划分成多个子问题。
- 判断子问题的局部最优解是否得出全局最优解
- 子问题必须具有无后效性
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
const int MAXN=1e5+10;
using namespace std;
struct programe{
int si; //记录节目起始时间
int ei; //记录节目结束时间
}stu[MAXN];
int cmp(const programe &a,const programe &b) //按照结束时间排序
{
if(a.ei!=b.ei) return a.ei<b.ei; //如果结束时间不等,则按结束时间将结构体升序排序
return a.si<b.si; //若结束时间相等,则按开始时间将结构体升序排序
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&stu[i].si,&stu[i].ei);
}
sort(stu,stu+n,cmp); //排序算法
int ans=0,tmp=0; //tmp记录前一个节目的结束时间,即能够符合要求的最晚开始时间
for(int i=0;i<n;i++)
{
if(stu[i].si >= tmp)
{
tmp=stu[i].ei;
ans++; //记录能观看节目总数
}
}
cout<<ans<<endl;
}
}
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
const int MAXN=1e6+5;
using namespace std;
long long T,n,m,k,f,max1=0;
long long a[MAXN];
int main()
{
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld%lld",&n,&m,&k); //n个柜子,要去m个快递,密码箱在第k个柜子
for(int i=0;i<m;i++)
{
scanf("%lld",&a[i]);
}
sort(a,a+m);//排序贪心,默认升序排序
max1=k-1; //第一步定为先走到k柜
for(int i=1;i<m;i++)
{
max1+=2*abs(a[i]-k); //前m-1个快递情况相同,均为a[i]柜到k柜一个来回
}
if(a[0]<k) //第m个快递分为在k柜左边和右边两种情况
max1+=k-1;
else
max1+=k-1+2*abs(a[0]-k);
printf("%lld\n",max1);
}
}
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
const int MAXN=1e4+5;
using namespace std;
int T,n,m;
long long ans,sum,time;
struct v11{
int hp,atk;
long long time;
}monster[MAXN];
bool cmp(struct v11 &x,struct v11 &y){
return (double)x.atk/x.time>(double)y.atk/y.time;
} //按照怪兽的攻击力和被打死需要的次数的出书除数降序排序
int main()
{
int k=1;
scanf("%d",&T);
while(T--)
{
ans=0,sum=0;
time=0;
scanf("%d%d",&n,&m);//n为怪兽个数,m为v11的atk
for(int i=0;i<n;i++)
{
scanf("%d%d",&monster[i].hp,&monster[i].atk);
monster[i].time=(monster[i].hp-1)/m+1; //第i个怪兽被打死需要的次数
}
sort(monster,monster+n,cmp); //对结构体排序
for(int i=0;i<n;i++)
{
time=time+monster[i].time;
ans+=time*monster[i].atk;
}
printf("Case #%d: %lld\n",k,ans);
k++;
}
}