贪心法
部分最优,结果最优(需证明)
贪心问题的特征:
1、一个问题的最优解包含其子问题的最优解
2、整体最优解可以通过局部的最优的选择
例题
老鼠的旅行
#include <bits/stdc++.h>
using namespace std;
struct sa
{
int j; // javabeen 的数量
int f; // 猫食的数量
double awk; // f[i]/j[i]的比值
} data[1001];
int cmp( const sa &a,const sa &b)
{
return (a.awk) > (b.awk);
}
int m,n;
double sum;
int k;
int main()
{
while(cin>>m>>n)
{
sum=0.0;
k=0;
if (m==-1&&n==-1)
break;
for(int i=0; i<n; i++)
{
cin>>data[i].j>>data[i].f;
data[i].awk=(double)data[i].j/(double)data[i].f ;
}
sort(data,data+n,cmp);
for(k=0; k<n; k++)
{
if (m>=data[k].f)//大于 F[i]
{
sum=sum+data[k].j; //都换了
m=m-data[k].f;
}
else
{
sum=sum+(double)m*data[k].awk;
break;
}
}
printf("%.3f\n",sum);
}
return 0;
}
今年暑假不AC
#include <bits/stdc++.h>
using namespace std;
struct sa
{
int x;
int y;
} data[105];
int cmp( const sa &a,const sa &b)
{
return a.y<b.y;
}
int main()
{
int n;
sa tmp;
while(cin>>n&&n!=0)
{
int sum;
for(int i=0; i<n; i++)
cin>>data[i].x>>data[i].y;
sort(data,data+n,cmp);
sum=1;
tmp=data[0];
for(int j=1; j<n; j++)
{
if (tmp.y<=data[j].x)
{
sum++;
tmp=data[j];
}
}
cout<<sum<<endl;
}
return 0;
}
Wooden Sticks
#include <bits/stdc++.h>
using namespace std;
struct sa
{
int x;
int y;
int flag;
} data[5005];
int cmp( const sa &a,const sa &b)//注意排序的方式
{
if (a.x!=b.x)
return (a.x)<(b.x);
else
return (a.y)<(b.y);
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data[i].x>>data[i].y;
data[i].flag=0;
}
sort(data,data+n,cmp);
int num=0;
for(int j=0; j<n; j++)
{
if (data[j].flag==1)
continue;
num++;
data[j].flag=1;
int tmp=j;
for(int k=j+1; k<n; k++)//先找一个小的,把后面能过的都过去
{
if (!data[k].flag&&data[k].x>=data[tmp].x&&data[k].y>=data[tmp].y)
{
data[k].flag=1;
tmp=k;
}
}
}
cout<<num<<endl;
}
return 0;
}
Moving Tables
#include <bits/stdc++.h>
using namespace std;
struct sa
{
int start;
int end;
int flag;
} data[501];
int cmp(const sa &a,const sa &b)
{
if (a.start!=b.start)
return (a.start)<(b.start);
else
return (a.end)<(b.end);
}
int main()
{
int t,n,count,tmp;
cin>>t;
while(t--)
{
cin>>n;
for(int i=0; i<n; i++)
{
cin>>data[i].start;
cin>>data[i].end;
if (data[i].start>data[i].end)//保证大的在前面
{
tmp=data[i].start;
data[i].start=data[i].end;
data[i].end=tmp;
}
data[i].flag=0;
}
sort(data,data+n,cmp);
count=0;
for(int j=0; j<n; j++)
{
if (data[j].flag==1)
continue;
count++;
tmp=j;
data[j].flag=1;
for(int k=j+1; k<n; k++)
{
if (!data[k].flag &&data[k].start>=data[tmp].end&& !(data[k].start%2==0&&(data[k].start-1==data[tmp].end)))
{
data[k].flag=1;
tmp=k;
}
}
}
cout<<count*10<<endl;
}
return 0;
}
区间覆盖-贪心
#include <bits/stdc++.h>
using namespace std;
int x[300],y[300];
int main()
{
int n,m;
cin>>n>>m;
int j=0;
for(int i=1; i<=n; i++)
cin>>x[i];
sort(x+1,x+1+n);
for(int i=1; i<=n; i++)
{
y[j]=x[i]-x[i-1]-1;
j++;
}
/*for(int i=1; i<n; i++)
cout<<y[i]<<" ";
cout<<endl;*/
sort(y,y+n,greater<int>());
/*for(int i=1; i<n; i++)
cout<<y[i]<<" ";
cout<<endl;*/
int res=x[n]-x[1];
//cout<<res<<endl;
for(int i=0; i<m-1; i++)
res=res-y[i];
cout<<res+1<<endl;
return 0;
}
等价交换
#include <bits/stdc++.h>
using namespace std;
struct sa
{
int t1;
int t2;
double awp;
} data[1000];
double cmp(const sa &a,const sa &b)
{
return a.awp>b.awp;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=0; i<m; i++)
{
cin>>data[i].t1>>data[i].t2;
data[i].awp=(double)data[i].t2/(double)data[i].t1;
}
sort(data,data+m,cmp);
double ans=0.0;
for(int i=0; i<m; i++)
{
if(n>=data[i].t1)
{
ans+=data[i].t2;
n=n-data[i].t1;
}
else
{
ans+=(double)n*data[i].awp;
break;
}
}
printf("%.2lf\n",ans);
}
return 0;
}