ACM算法笔记 03 贪心算法

1.贪心算法不从整体上考虑,而是求出在某种意义上的当前局部最优解,但要求当前的局部最优解就是全局整合后的全局最优解(需要证明,但一般很难,可以考虑反证法)。
2.证明贪心算法的局部最优解的合理性:
*方法1:枚举
*方法2:反证法
3.贪心算法常见的操作:排序
*qsort C
*sort() C++

0.fatmouse’s trade

1.本题解决的坑:C语言中/是整除,整除的结果直接去除小数部分,无法比较大小
image.png
image.png

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.
image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值