贪心算法基础专练

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

猜你喜欢

转载自blog.csdn.net/weixin_43105110/article/details/85194426