貪心繫列

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;
}



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