算法竞赛宝典-贪心算法

/*删数问题
#include <iostream>
using namespace std;
int main()
{
    string n;
    cin>>n;
    int len=n.length();
    int s;
    cin>>s;
    int i,j,k;
    for(i=1;i<=s;i++)
    {
        for(j=1;j<len;j++)
        {
            if(n[j]<n[j-1])
            {
                break;
            }
        }
        if(j<len)//找到递减区间时删除递减区间第一个
        {
            len--;
            for(k=j-1;k<len;k++)
            {
                n[k]=n[k+1];
            }
        }
        else{//全是递增区间时从后面开始删
            len--;
        }
    }
    int ii=0;//去除前导零再输出
    while(n[ii]=='0'&&ii<len)
    {
        ii++;
    }
    if(ii==len) cout<<"0";
    else {
        for(int i=ii;i<len;i++)
        {
            cout<<n[i];
        }
    }
    return 0;
}*/
/*数列极差问题
#include <iostream>
#include <algorithm>
using namespace std;

#define maxn 99999999;
#define minn -1;

int main()
{
    int n;
    cin >> n;
    int a[50000 + 10],b[50000+10];
    for(int i = 0;i < n;i ++ )
    {
        cin >> a[i];
        b[i]=a[i];
    }
    int len=n;
    while(len>1)//求max
    {
        sort(a,a+n);
        a[0]=a[0]*a[1]+1;
        a[1]=maxn;
        len--;
    }
    int max1=a[0];

    int len2=n;
    while(len2>1)//求min
    {
        sort(b,b+n);
        b[n-1]=b[n-1]*b[n-2]+1;
        b[n-2]=minn;
        len2--;
    }
    int min2=b[n-1];

    cout<<max1-min2<<endl;
    return 0;
}*/
/*不相交区间问题*/
/*电视节目安排
#include <iostream>
#include <algorithm>
using namespace std;

typedef struct ds{
    int x;
    int y;
}DS;
DS T[100+10];

bool cmp(DS s1,DS s2)
{
    return s1.y<s2.y;
}

int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0) break;
        for(int i=0;i<n;i++)
        {
            cin>>T[i].x>>T[i].y;
        }
        sort(T,T+n,cmp);
        int Y=T[0].y;
        int ans=1;//第一次选择x1到y1
        for(int i=1;i<n;i++)
        {
            if(T[i].x>=Y)//循环只选不相交的(开区间>=)
            {
                Y=T[i].y;
                ans++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
*/
/*区间选点问题*/
/*监测点
#include <iostream>
#include <algorithm>
using namespace std;

typedef struct qj{
    int x;
    int y;
}QJ;
QJ a[100+10];

bool cmp(QJ s1,QJ s2)
{
    if(s1.y!=s2.y)
    {
        return s1.y<s2.y;//y从小到大排序
    }
    else{
        return s1.x>s2.x;//当y相等时x从大到小排序
    }
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>a[i].x>>a[i].y;
        }
        sort(a,a+n,cmp);
        int ans=1;//第一个点是啊a[0].y
        int Y=a[0].y;
        for(int i=1;i<n;i++)
        {
            if(a[i].x>Y)
            {
                Y=a[i].y;//更新右端点
                ans++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
*/

/*雷达问题*/

/*广告问题*/

/*区间覆盖问题*/
/*时空定位1
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int n,m;
double a[600+10];

bool cmp(double s1,double s2)
{
    return s1>s2;
}

int main()
{
    cin>>m;
    while(m--)
    {
        int i;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>a[i];
        }
        sort(a,a+n,cmp);
        double length=0;
        for(i=0;i<n;i++)
        {
            length=length+2.0*(sqrt(a[i]*a[i]-1));
            if(length>=20.0)
                break;
        }
        cout<<i+1<<endl;
    }
    return 0;
}
*/
/*时间定位2
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

struct qj1{
    int a1;
    int b1;
}a[10000+10];
struct qj2{
    double a2;
    double b2;
}b[10000+10];
bool cmp(qj2 s1,qj2 s2)
{
    return s1.a2<s2.a2;
}

int main()
{
    int N;
    cin>>N;
    while(N--)
    {
        int n,w,h;
        cin>>n>>w>>h;

        for(int i=0;i<n;i++)
        {
            cin>>a[i].a1>>a[i].b1;
        }

        int j=0;
        for(int i=0;i<n;i++)
        {
            if(a[i].b1*1.0>h/2.0)
            {
                b[j].a2=a[i].a1*1.0-sqrt(a[i].b1*a[i].b1*1.0-h*h*1.0/4.0);
                if(b[j].a2<0) b[j].a2=0;
                b[j].b2=a[i].a1*1.0+sqrt(a[i].b1*a[i].b1*1.0-h*h*1.0/4.0);
                if(b[j].b2>w) b[j].b2=w;
                j++;
            }
        }
        sort(b,b+j,cmp);

        bool flag=1;
        int ans=0,i=0;
        double maxlen=0,p=0;

        while(p<w*1.0)
        {
            maxlen=0;
            for(i;b[i].a2<=p&&i<j;i++)
            {
                if(b[i].b2-p>=maxlen)
                {
                    maxlen=b[i].b2-p;
                }
            }
            if(!maxlen)
            {
                flag=0;
                break;
            }
            p+=maxlen;
            ans++;
        }
        if(!flag)
            cout<<"0"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}
*/
/*平均分配问题*/
/*均分纸牌
#include <iostream>
using namespace std;

int a[110];

int main()
{
    int N;
    cin>>N;
    int ans=0;
    for(int i=0;i<N;i++)
    {
        cin>>a[i];
        ans+=a[i];
    }
    ans/=N;
    for(int i=0;i<N;i++)
    {
        a[i]=a[i]-ans;
    }
    int total=0;
    for(int i=0;i<N;i++)
    {
        if(a[i]!=0)
        {
            a[i+1]+=a[i];
            total++;
            a[i]=0;
        }
    }
    cout<<total<<endl;
    return 0;
}*/
/*作业调度问题(johnson算法)*/
/*流水作业调度问题
#include <iostream>
#include <algorithm>
using namespace std;

struct jg{
    int a;
    int b;
}x[10000+10],y[10000+10],z[10000+10];

bool cmp1(jg s1,jg s2)
{
    return s1.a<s2.a;
}
bool cmp2(jg s1,jg s2)
{
    return s1.b>s2.b;
}

int main()
{
    int n;
    while(cin>>n)
    {
        if(n==0) break;//将作业按加工时间分为两个集合
        int j=0,k=0;
        for(int i=0;i<n;i++)
        {
            cin>>x[i].a>>x[i].b;
            if(x[i].a<x[i].b)//M1加工时间少于M2
            {
                y[j].a=x[i].a;
                y[j].b=x[i].b;
                j++;
            }
            else {//M1加工时间大于等于M2
                z[k].a=x[i].a;
                z[k].b=x[i].b;
                k++;
            }
        }

        sort(y,y+j,cmp1);//M1加工时间小于M2的,按M1上的时间递增排序
        sort(z,z+k,cmp2);//M1加工时间大于M2的,按M2上的时间递减排序

        for(int i=0;i<n;i++)//合并到一个集合
        {
            if(i<j)
            {
                x[i].a=y[i].a;
                x[i].b=y[i].b;
            }
            else
            {
                x[i].a=z[i-j].a;
                x[i].b=z[i-j].b;
            }
        }

        int c[10000+10]={0};//计算最少时间
        for(int i=1;i<n;i++)
        {
            c[i]=c[i-1]+x[i-1].a;
        }
        int sum=0;
        for(int i=0;i<n;i++)
        {
            if(sum<c[i+1])
            {
                sum=c[i+1]+x[i].b;
                cout<<sum<<endl;
            }
            else sum=sum+x[i].b;
        }
        cout<<sum<<endl;
    }
    return 0;
}
*/
/*赶作业
#include <iostream>
#include <algorithm>
using namespace std;

struct zy{//作业
    int s;
    int f;
}a[1000+10];
bool cmp(zy s1,zy s2)
{
    if(s1.f!=s2.f) return s1.f>s2.f;
    else return s1.s<s2.s;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>a[i].s;
        }
        for(int i=0;i<n;i++)
        {
            cin>>a[i].f;
        }

        sort(a,a+n,cmp);

        int j;
        int sum=0;
        bool flag[1000+10]={0};
        for(int i=0;i<n;i++)
        {
            for(j=a[i].s;j>0;j--)
            {
                if(flag[j]==0)
                {
                    flag[j]=1;
                    break;
                }
            }
            if(j==0)
                sum=sum+a[i].f;
        }
        cout<<sum<<endl;
    }
    return 0;
}
*/

/*钓鱼*/

/*田忌赛马*/

/*洛谷题目*/
/*P1233 木棍加工
#include <iostream>
#include <algorithm>
using namespace std;

struct mg{
    int l;
    int w;
}a[5000+10];
bool cmp(mg s1,mg s2)
{
    if(s1.l!=s2.l)
        return s1.l>=s2.l;
    else return s1.w>=s2.w;
}
int b[5000+10];

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)//输入
    {
        cin>>a[i].l>>a[i].w;
        b[i]=0;
    }

    sort(a,a+n,cmp);//按l从大到小排序

    for(int i=0;i<n;i++)//找出宽度不增序列
    {
        if(b[i]==0){
            for(int j=i+1;j<n;j++)
            {
                if(a[j].w<=a[i].w&&b[j]==0)
                {
                    b[j]=1;
                    a[i].w=a[j].w;
                }
            }
        }
    }

    int ans=0;//输出
    for(int i=0;i<n;i++)
    {
        if(b[i]==0) ans++;
    }
    cout<<ans<<endl;

    return 0;
}
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值