贪心策略——总是做出当前最好的选择
1.问题分解成为多个子问题
2.子问题求局部最优解
3.局部最优解组合成原问题的解
简单贪心
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1000;
struct JavaBean
{
double weight;
double cost;
};
JavaBean arr[MAXN];
bool Compare(JavaBean x,JavaBean y)
{
return x.weight/x.cost>y.weight/y.cost;
}
int main()
{
int n,m;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(n==-1&&m==-1)
{
break;
}
for(int i=0;i<n;++i)
{
scanf("%lf%lf",&arr[i].weight,&arr[i].cost);
}
sort(arr,arr+n,Compare);
double answer=0;
for(int i=0;i<n;++i)
{
if(m>=arr[i].cost)
{
m-=arr[i].cost;
answer+=arr[i].weight;
}else
{
answer+=arr[i].weight*(m/arr[i].cost);
m=0;
break;
}
}
printf("%.3f\n",answer);
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100000+10;
long long gun[MAXN];
long long monster[MAXN];
bool Compare(long long x,long long y)
{
return x>y;
}
int main()
{
int caseNumber;
scanf("%d",&caseNumber);
while(caseNumber--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
{
scanf("%lld",&gun[i]);
}
for(int i=0;i<m;++i)
{
scanf("%lld",&monster[i]);
}
sort(gun,gun+n,Compare);
sort(monster,monster+m);
long long answer=0;
for(int i=0;i<n;++i)
{
if(i>=m||gun[i]<=monster[i])
{
break;
}
answer+=gun[i]-monster[i];
}
printf("%lld\n",answer);
}
return 0;
}
#include<iostream>//箱子
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
int length[MAXN];
bool Compare(long long x,long long y)
{
return x>y;
}
int main()
{
int n,l;
scanf("%d%d",&n,&l);
for(int i=0;i<n;++i)
{
scanf("%d",&length[i]);
}
sort(length,length+n);
int left=0;
int right=n-1;
int answer=0;
while(left<=right)
{
if(length[left]+length[right]<=l)
{
left++;
right--;
}
else
{
right--;
}
answer++;
}
printf("%d\n",answer);
return 0;
}
最大的最小间距:二分策略 最值问题→判定性问题
#include<iostream>//最大的最小值
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
int arr[MAXN];
bool Judge(int n,int m,int distance)
{
int current=arr[0];
int number=1;
for(int i=1;i<n;++i)
{
if(arr[i]-current>=distance)
{
number++;
current=arr[i];
}
if(number>=m)
{
return true;
}
}
return false;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;++i)
{
scanf("%d",&arr[i]);
}
sort(arr,arr+n);
int left=1;
int right=arr[n-1]-arr[0];
while(left<=right)
{
int middle=left+(right-left)/2;
if(Judge(n,m,middle))
{
left=middle+1;
}
else
{
right=middle-1;
}
}
printf("%d\n",right);
}
return 0;
}
#include<iostream>//最小值
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
int water[MAXN];
bool Judge(int n,int k,int time)
{
int sum=0;
for(int i=0;i<n;++i)
{
if(water[i]>time)
{
sum+=ceil((water[i]-time)*1.0/(k-1));
}
if(sum>time)
{
return false;
}
}
return true;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
scanf("%d",&water[i]);
}
int k;
scanf("%d",&k);
sort(water,water+n);
if(k==1)
{
printf("%d\n",water[n-1]);
}
else
{
int left=1;
int right=water[n-1];
while(left<=right)
{
int middle=left+(right-left)/2;
if(Judge(n,k,middle))
{
right=middle-1;
}
else
{
left=middle+1;
}
}
printf("%d\n",left);
}
return 0;
}
区间贪心
#include<iostream>//看尽可能多的节目
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=100+10;
struct program
{
int startTime;
int endTime;
};
program arr[MAXN];
bool Compare(program x,program y)
{
return x.endTime<y.endTime;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
{
break;
}
for(int i=0;i<n;++i)
{
scanf("%d%d",&arr[i].startTime,&arr[i].endTime);
}
sort(arr,arr+n,Compare);
int current=0;
int answer=0;
for(int i=0;i<n;++i)
{
if(current<=arr[i].startTime)
{
current=arr[i].endTime;
answer++;
}
}
printf("%d\n",answer);
}
return 0;
}
#include<iostream>//覆盖范围尽可能小
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=1000+10;
struct Interval
{
double left;
double right;
};
Interval arr[MAXN];
bool Compare(Interval x,Interval y)
{
return x.left<y.left;
}
int main()
{
int n,d;
int caseNumber=0;
while(scanf("%d%d",&n,&d)!=EOF)
{
if(n==0&&d==0)
{
break;
}
bool flag=true;
for(int i=0;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
if(y>d)
{
flag=false;
}else
{
arr[i].left=x-sqrt(d*d-1.0*y*y);
arr[i].right=x+sqrt(d*d-1.0*y*y);
}
}
if(!flag)
{
printf("Case %d:%d\n",++caseNumber,-1);
}else
{
sort(arr,arr+n,Compare);
double current=arr[0].right;
int answer=1;
for(int i=1;i<n;++i)
{
if(arr[i].left<=current)
{
current=min(current,arr[i].right);
}else
{
current=arr[i].right;
answer++;
}
}
printf("Case %d:%d\n",++caseNumber,answer);
}
}
return 0;
}