1. 程式人生 > >貪心演算法基礎專練

貪心演算法基礎專練

A.智力大沖浪
由於本題要求的是小偉能贏取得最多的錢,所以我們只要用m減去扣款數最低的不可執行遊戲即可。因此,要先對每個遊戲的扣款數由大到小排序,優先安排價值最大的遊戲,如果該遊戲的期限已經有安排,就從他的期限向下遍歷,直到1,如果都有安排,那就是不可執行遊戲。

#include<stdio.h>
int main()
{
    int m,n,l[505][2],x,sum=0,k[505];
    for(int i=0;i<505;i++)
        k[i]=0;
    scanf("%d",&m);
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&l[i][0]);
    for(int i=0;i<n;i++)
        scanf("%d",&l[i][1]);
    for(int i=0;i<n-1;i++)
        for(int j=0;j<n-1;j++)
        if(l[j][1]<l[j+1][1])
        {x=l[j][1];l[j][1]=l[j+1][1];l[j+1][1]=x;
        x=l[j][0];l[j][0]=l[j+1][0];l[j+1][0]=x;}
    for(int i=0;i<n;i++)
        for(int a=l[i][0]-1;a>=0;a--)
        {
            if(k[a]==0)
            {
                l[i][1]=0;
                k[a]=1;
                break;
            }
        }
    for(int i=0;i<n;i++)
        sum+=l[i][1];
    printf("%d\n",m-sum);
    return 0;
}

B.數列極差
通過觀察我們可以發現,如果每次都刪去數列中最小的兩個數,那麼最後剩下的那個數一定是max,反之,剩下的那個數一定是min。要注意的是每次都要刪去最小的兩個數,所以刪完兩個數a,b並加上a*b+1後一定要再次對數列排序。當時就是因為沒有想到這一點WA了一次。由於這個題要多次用到排序,所以用c++的sort函式比較方便。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,l[50005],m[50005],x;
    while(scanf("%d",&n)!=EOF)
    {
        x=n;
        if(n==0)break;
        for(int i=0;i<n;i++)
            scanf("%d",&l[i]);
        memcpy(m,l,sizeof(l));
        sort(l,l+n);
        int a=1;
        while(a<n)
        {
            l[a]=l[a]*l[a-1]+1;
            l[a-1]=0;
            sort(l,l+n);
            a++;
        }
        sort(m,m+n,greater<int>());
        int b=0;
        while(n>1)
        {
            m[b]=m[b+1]*m[b]+1;
            m[b+1]=0;
            sort(m,m+n,greater<int>());
            b=0;
            n--;
        }
        printf("%d\n",l[x-1]-m[0]);
    }
    return 0;
}

C.數列分段
這個題要注意題幹中的連續的若干段,因此不能對輸入的資料進行排序,只要將輸入的資料儲存在陣列中遍歷求每段的和即可。

#include<stdio.h>
int main()
{
    int N,M,l[100000],ans=0;
    scanf("%d%d",&N,&M);
    for(int i=0;i<N;i++)
        scanf("%d",&l[i]);
    int a=0;
    while(a<=N)
    {
        int b=0;
        while(b<=M)
        {
            b+=l[a];
            a++;
        }
        ans++;
        a--;
    }
    printf("%d\n",ans);
    return 0;
}

D.線段
這個題我開始用的陣列,但不知道為什麼,點選執行後在輸入框內輸入數字輸入框就會自動關閉。然後轉換成結構體,一頓操作猛如虎,忽然發現我忘了結構體怎樣用了T^T。然後請教了其他dalao,終於搞定了,思路和會場安排的思路一樣,不多bb,直接看程式碼。

#include<bits/stdc++.h>
using namespace std;
struct abc
{
    int a;
    int b;
}xian[1000005];
bool cmp(abc m,abc n)
{
    return m.b<n.b;
}
int main()
{
    int n,x,y;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d%d",&xian[i].a,&xian[i].b);
    sort(xian,xian+n,cmp);
    x=1;y=xian[0].b;
    for(int i=0;i<n-1;i++)
    if(xian[i+1].a>=y){x++;y=xian[i+1].b;}
    printf("%d\n",x);
    return 0;
}