ACM选修课5 贪心法

贪心法

部分最优,结果最优(需证明)

贪心问题的特征:
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;
}

猜你喜欢

转载自blog.csdn.net/qq_46126537/article/details/105521934