贪心系列

1.(区间覆盖)POJ2376poj2376

题意:每头牛都有清洁的时间段,给出一个1-n的时间段,用最少的牛使得每个时间内、点都有牛工作。

思路:要用最少的牛,首先选的牛工作时间要尽可能长,并且要覆盖时间点。我们先对牛的工作的起始时间按从小到大排序,然后再选起始时间小于等于上一头牛的结束时间并且结束时间尽可能大的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct cow
{
    int start;
    int ended;
}A[25005];
typedef struct cow cow;
bool cmp(cow a,cow b)
{
    if(a.start==b.start)
        return a.ended>b.ended;
    else
        return a.start<b.start;
}//对牛的起始时间按从小到大排序
int main()
{
    int n,h;
    while(scanf("%d%d",&n,&h)!=EOF)
    {
        int i;
        for(i=0;i<n;i++)
            scanf("%d%d",&A[i].start,&A[i].ended);
        sort(A,A+n,cmp);
        A[n].start=1000005;
        int temp=0,ans=0,t=0;
        int tag=0;
        for(i=0;i<n;i++)
        {
            if(A[i].start<=t+1)//第一头判断起始时间等于一,其他是否小于等于上一头的结束时间+1
            {
                if(A[i].ended>=temp+1)
                {
                    temp=A[i].ended;
                    tag=1;
                    if(A[i].ended>h)
                        break;
                }
                if(A[i+1].start>t+1&&tag)
                {
                    t=temp;
                    ++ans;
                    tag=0;
                }
            }
        }//随时更新开始和结时间
        if(t<h)
            printf("-1\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

2.(区间选点)poj1328poj1328

思路:先对座标的每个点进行预处理,在雷达所能到的距离间点与座标的交点,找到一个区间。依次处理。再对区间进行排序,找最少的点使得每个区间都含有点。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct tt
{
    double x;
    double y;
}A[1005];
typedef struct tt tt;
bool cmp1(tt d1,tt d2)
{
    if(d1.y==d2.y)
        return d1.x>d2.x;
    else
        return d1.y<d2.y;
}
int main()
{
    int n,d;
    int i,j;
    int k=1;
    while(scanf("%d%d",&n,&d)!=EOF)
    {
        int tag=0;
        int co=0;
        if(n==0&&d==0)
           break;
        for(i=0;i<n;i++)
        {
            int s,l;
            scanf("%d%d",&s,&l);
            if(l>d)
                tag=1;//找不到交点
            else
            {
                A[i].x=s-sqrt((double)d*d-l*l);
                A[i].y=s+sqrt((double)d*d-l*l);
            }//把以点为中心半径为d的与x轴的两个交点找到,找到一个区间
        }
        sort(A,A+n,cmp1);//对区间进行排序
        double temp=A[0].y;//标记右区间
        for(i=1;i<n;i++)
        {
            if(A[i].x>temp)
            {
                co++;
                temp=A[i].y;
            }//如果左区间大于前面右区间,没有公共点,雷达数加1,更新右区间
        }
        if(tag==1)
            printf("Case %d: -1\n",k++);
        else
            printf("Case %d: %d\n",k++,co+1);
    }
    return 0;
}

3.poj3190poj3190

思路:先按牛挤奶的开始时间从小到大排序,让结束快的牛先挤奶。采用优先队列。

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
struct cow
{
    int bg;
    int ed;
    int loc;//标记为第几头牛
    friend bool operator<(cow a,cow b)
    {
        return a.ed>b.ed;
    }//定义优先级。>是从小到大排序
}A[50005];
bool cmp(struct cow a,struct cow b)
{
    return a.bg<b.bg;
}//对牛挤奶的起始时间从小到大排序
int main()
{
    int n;
    int N[50005];
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        int co=1;
        priority_queue<struct cow>q;//定义一个优先队列q
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&A[i].bg,&A[i].ed);
            A[i].loc=i;
        }
        sort(A,A+n,cmp);
        q.push(A[0]);//一定先放地一头牛在队首
        N[A[0].loc]=co;//第A[i].loc头牛所在棚
        for(i=1;i<n;i++)
        {
            if(A[i].bg<=q.top().ed)
            {
                q.push(A[i]);
                co++;
                N[A[i].loc]=co;
            }//另用一个牛棚
            else
            {
                N[A[i].loc]=N[q.top().loc];
                q.pop();
                q.push(A[i]);
            }//如果找到一头牛的起始时间大于队首的结束时间,踢出队首,放入牛
        }
        printf("%d\n",co);
        for(i=0;i<n;i++)
        printf("%d\n",N[i]);


    }
    return 0;
}
4.poj2393poj2393

思路:尽可能在成本低的时候成产完下周甚至以后的酸奶。由于有储存费,所以应该加储存费来比较出最小的成本。

#include<stdio.h>
int minn(int a,int b)
{
    return a>b?b:a;
}
int main()
{
    int x[10005],t[10005];
    int n,s;
    while(scanf("%d%d",&n,&s)!=EOF)
    {
        int i;
        long long sum=0;
        for(i=0;i<n;i++)
            scanf("%d%d",&x[i],&t[i]);
        for(i=1;i<n;i++)
            x[i]=minn(x[i],x[i-1]+s);//找到i周的最小的成本
        for(i=0;i<n;i++)
            sum=sum+x[i]*t[i];
        printf("%I64d\n",sum);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章