1.贪心算法不从整体上考虑,而是求出在某种意义上的当前局部最优解,但要求当前的局部最优解就是全局整合后的全局最优解(需要证明,但一般很难,可以考虑反证法)。
2.证明贪心算法的局部最优解的合理性:
*方法1:枚举
*方法2:反证法
3.贪心算法常见的操作:排序
*qsort C
*sort() C++
0.fatmouse’s trade
1.本题解决的坑:C语言中/
是整除,整除的结果直接去除小数部分,无法比较大小
1.事件序列问题 今年暑假不AC
1.局部贪心策略:选择结束最早的
*证明:至少存在一个最长序列a1,a2,a3,a4,a5...an
,且都包含最早结束的a1
*反证法:假设最长序列都不包含最早结束,则举反例,即可证明假命题
2.选择策略思路:最早开始,最早结束,时间最短,三种策略,代入例子简单选择后,得到初始结论;反证法证明尝试
3.
#include <iostream>
#include <algorithm>
using namespace std;
struct time{
int start;
int end;
}list[100];
bool cmp(struct time a,struct time b){
return a.end<b.end;
}
int main(){
int n;
while(cin>>n&&n!=0){
int number=1;
for(int i=0;i<n;i++) cin>>list[i].start>>list[i].end;
sort(list,list+n,cmp);
int temp=list[0].end;
for(int i=1;i<n;i++){
if(list[i].start>=temp){
number+=1;
temp=list[i].end;
}
}
cout<<number<<endl;
}
return 0;
}
2.搬箱子 Moving Tables
选择最高重叠度
1.解题相关的内置函数#include <algorithm> max=max(a,b);
*#include <bits/stdc++.h> swap(a,b);``a``b``可以是任意参数类型
3.田忌赛马
*双向贪心,用4个变量标注king max min,tianji max min
1.这道题我写的时候比较懵圈,没有思路,以下是参考正解后我归纳出的思路:
*本题贪心思路的关键:用最慢的消耗最好的
2.思路:
*比较ji和king的快马
*如果ji的快马快于王的快马,那么直接比赛
*如果ji的快马慢于王的快马,直接用ji的慢马换王的快马
*如果ji和王的快马速度一样,比较二者的慢马
*如果ji的慢马比王的慢马快,用ji的慢马换王的慢马
*如果ji的慢马比王的慢马慢,用ji的慢马换王的快马
*如果二者相等,也依旧用ji的慢马换王的快马
3.
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[3000],b[3000];
int cmp(int a,int b)
{
return a>b;
}
int main()
{
int i,n,j,sum,k,f,ji;
while( scanf("%d",&n) && n!=0 )
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
scanf("%d",&b[i]);
sort(a,a+n,cmp);
sort(b,b+n,cmp);
ji=0;
i=j=sum=0;
k=n-1;
f=n-1;
while(1)
{
if(ji==n) break;
if(b[j]>a[i]) {
sum-=200;
j++;
k--;
ji++;
continue;
}
if(b[j]==a[i]){
if(b[f]<a[k]){f--;k--;sum+=200;ji++;continue;}
if(b[j]>a[k]){sum-=200;k--;j++;ji++;}
else {k--;j++;ji++;}
continue;
}
if(b[j]<a[i]){sum+=200;j++;i++;ji++;continue;}
}
printf("%d\n",sum);
}
}
4.青蛙的邻居
1.可图性判定(havel-hakimi)
2.有趣的是,我刚开始没AC,报错运行超时,我添加一行if(flag==0)break;
之后AC了
3.
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main(){
int T;
cin>>T;
int list[1000];
for(int i=0;i<T;i++){
int n;
cin>>n;
for(int j=0;j<n;j++) cin>>list[j];
sort(list,list+n,cmp);
// 0 indicates no
// 1 indicates yes
int flag=1;
while(list[0]!=0){
int num=list[0];
if(num>n-1){
flag=0;
break;
}else{
list[0]=0;
for(int k=1;k<=num;k++){
list[k]-=1;
if(list[k]<0){
flag=0;
break;
}
}
if(flag==0)
break;
}
sort(list,list+n,cmp);
}
if(list[0]==0&&flag==1)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
5.关于特别说明的理由
DP与贪心,找钱问题
DP 币值:11分 5分 1分
贪心 币值:10分 5分 1分
*倍数关系
6.sort() C++
1.头文件:#include
2.格式:sort(首地址,尾地址+1,cmp函数),如int a[100] sort(a,a+100,cmp) bool cmp(int a,int b){return a>b;}
,cmp函数不写,默认递增排序
3.关于cmp函数bool cmp(a,b) return a>b
大到小排序bool cmp(a,b) { if (x.a!=y.a) return x.a<y.a return x.b<y.b}
结构体,a升序,b降序
*fabs(float1,float2)>0.000001
4.关于结构体的定义与初始化https://blog.csdn.net/m0_60259116/article/details/132190233
5.