算法之贪心算法篇

hdu1257

  题目刚开始理解错了,该题可以同时有几个拦截系统并行的。题目不算难。

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int height;
        vector<int> v;
        for(int i=0;i<n;++i)
        {
            scanf("%d",&height);
            int vsize = v.size();
            int j;
            for(j=0;j<vsize;++j)
            {
                if(v[j] >= height)
                {
                    v[j] = height;
                    break;
                }

            }
            if(j>=vsize)
                v.push_back(height);
        }
        printf("%d
",v.size());
    }
    return 0;
}
View Code

hdu1789。

  题意:t组测试数据,n个作业,每个作业需要一天完成,接下两行表示n个最后交作业时间,n个对应作业分数。

如果作业没有在最后时间提交,将会扣掉对应作业分数,求最小扣分数。

  思路:声明ST st[n],其中st[i].d表示时间限制,st[i].s表示分数。先对数据st数组进行按作业分数从大到小sort。然后在申请一个temp数组,向里面填充数据。对st数组从0到n-1遍历,d=st[i].d,然后如果temp[d]不为0,则temp[d]=1;如果填充过(temp[d]==1) ,则d--循环填充,如果d==0,则表示该门课只能放弃了。

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct ST
{
    //d表示时间限制,s表示分数。
    int d;
    int s;
};
bool Comp(ST s1,ST s2)
{
    return s1.s > s2.s;
}
int main()
{
    int t;//测试组数
    scanf("%d",&t);
    while(t--)
    {
        int n;//个数
        scanf("%d",&n);
        ST st[n];
        for(int i=0;i<n;++i)
            scanf("%d",&st[i].d);
        for(int i=0;i<n;++i)
            scanf("%d",&st[i].s);
        sort(st,st+n,Comp);     //按分数从高到低排
        //temp作用标记那天要做作业。
        int temp[n+1],res = 0;
        memset(temp,0,sizeof(temp));
        for(int i=0;i<n;++i)
        {
            //本来是d=st[i].d,导致了超时错误
            int d = min(st[i].d,n);
            while(d > 0)
            {
                if(temp[d]==0)
                {
                    temp[d] = 1;
                    break;
                }
                --d;
            }
            if(d <= 0)
                res += st[i].s;
        }
        printf("%d
",res);
    }
    return 0;
}
View Code

hdu2111。

  这道题目是典型的贪心问题,很简单。刚开始的时候看成了0,1背包,后来发现是单价,不是总价==。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct ST
{
    int pi;     //单价
    int mi;     //容量
};
bool comp(ST s1,ST s2)
{
    return s1.pi > s2.pi;
}


int main()
{
    int v;
    while(~scanf("%d",&v),v)
    {
        int n;      //v代表容量,n代表种类
        scanf("%d",&n);
        ST st[n];
        for(int i=0;i<n;++i)
            scanf("%d%d",&st[i].pi,&st[i].mi);
        sort(st,st+n,comp);
        int res = 0;
        for(int i=0;i<n&&v>0;++i)
        {
            if(v>=st[i].mi)
            {
                v -= st[i].mi;
                res += st[i].mi*st[i].pi;
            }
            else
            {
                res += v*st[i].pi;
                v = 0;
            }
        }
        printf("%d
",res);
    }
    return 0;
}
View Code

hdu4296,此题感觉题意有问题,不想说。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
//求木块之上的重量和减去该木板的强度的最小值。
struct ST
{
    int w;  //重量
    int s;  //强度
};
bool Comp(ST s1,ST s2)
{
    return s1.w + s1.s < s2.w + s2.s;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        ST st[n];
        for(int i=0;i<n;++i)
            scanf("%d%d",&st[i].w,&st[i].s);
        sort(st,st+n,Comp);
        __int64 Max = 0;
        __int64 sum = st[0].w;
        for(int i=1;i<n;++i)
        {
            __int64 temp = sum - st[i].s;
            Max = max(Max,temp);
            sum += st[i].w;
        }
        printf("%I64d
",Max);
    }
    return 0;
}
View Code

hdu4864,题目挺难的,看了网上的解题思路才做出来的。是贪心加hash法,没有hash法容易超时。

  题目是机器人n,任务数m,每个机器人只能做一个任务,机器人与任务都有x,y值,x表示时间,y表示等级。

只有当机器人的mac.x >= task.x 和 mac.y >= task.y都满足时,才表示该任务能被完成。完成任务后的收益是500*x + 2*y;求最大完成任务数与最大收益。

  

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

struct ST
{
    int x;  //时间
    int y;  //等级
    int getRes(){return 500*x + 2*y;}
};

bool cmp(ST st1,ST st2)
{
    if(st1.x != st2.x)
        return st1.x > st2.x;
    return st1.y > st2.y;
}

int main()
{
    int n,m;    //机器人数,任务数
    while(~scanf("%d%d",&n,&m))
    {
       ST mac[n],task[m];
       for(int i=0;i<n;++i)
          scanf("%d%d",&mac[i].x,&mac[i].y);
       for(int i=0;i<m;++i)
          scanf("%d%d",&task[i].x,&task[i].y);
       sort(mac,mac+n,cmp);
       sort(task,task+m,cmp);
       int Hash[101]={0};
       __int64 sum = 0;
       int cnt = 0;
       for(int i=0,j=0;i<m;++i)
       {
           while(j<n && mac[j].x >= task[i].x)
               ++Hash[mac[j++].y];
           for(int k=task[i].y;k<=100;++k)
           {
               if(Hash[k])
               {
                   --Hash[k];
                   sum += task[i].getRes();
                   ++cnt;
                   break;
               }
           }
       }
       printf("%d %I64d
",cnt,sum);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/jlyg/p/6672338.html