2019年3月20日

这几天一直做题,越发感到,贪心并不是一种技巧,而更多的是一种思考方式。
从这几天的题目来看,一个需要贪心的题,如果不是没有想到具体怎么贪,那么难度会瞬间倍增,但是一旦想通了,就会发现这道题太简单了。
(不得不吐槽一句vj的提交题目的系统,C和D无论我怎么搞,都是submit failed,试了试其他的直接就可以判断出WA,我对这个系统真的是无语了)
下面来一类例题。
超市往外卖东西,给你物品的价值和物品售卖的截止时间,求卖得的最大利润。
这道题的贪心的思路是:
首先,假设所有的物品都是在截止日期卖出的。
那么首先对价格排序,让贵的东西在它截止的那天卖出。
如果按照价格排序顺下来,有稍便宜的物品与贵的物品的截止日期是同一天
那么就从截止日期开始向前提前,看哪一天是空闲的,接着,卖出物品。
下面是代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<cstring>
#define ll long long
using namespace std;
struct box  //定义结构体
{
    int pri;
    int tim;
};
bool cmp(box x,box y) //按照价格大小排序
{
    return x.pri>y.pri;
}
int main()
{
	int n;
	while(~scanf("%d",&n))
    {
        int sum=0;
        box a[100000];
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i].pri);
            scanf("%d",&a[i].tim);
        }
        sort(a,a+n,cmp);  //从这里开始是代码的核心部分
        bool v[100000]; //定义bool数组,看哪一天是否卖出东西
        memset(v,0,sizeof(v));
        for(int i=0;i<n;i++)
        {
            if(!v[a[i].tim])  //如果空闲,那么卖出
            {
                sum+=a[i].pri;
                v[a[i].tim]=true;
            }
            else //不空闲,向前追溯
            {
                for(int j=a[i].tim-1; j>=1; --j)
                if(!v[j])
                {
                    sum+=a[i].pri;
                    v[j] = true;
                    break;
                }
            }
        }
        cout<<sum<<endl;   //输出
    }
	return 0;
}

还有一个与他相似的题目
主要内容是
给定作业的完成期限,和如果逾期所扣的分数,求最后最少扣的分数。
对于这个题目,与上个题目的思路是完全一样的。
首先,假设所有作业都在最后期限完成。
按照索扣分值排序,优先完成扣分值多的。
如果最后期限冲突,那么就往前追溯。
可以说两个题的模板是一抹一样的。
只不过计数方式有差异。
上一个需要计算的是能安排上的求和,这一个是按排不上的求和。
贴代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include<iostream>
using namespace std;
struct Node
{
    int d; //日期
    int s; //分数
} data[1005];
int v[1005];
int cmp (Node a, Node b) //排序
{
    if (a.s != b.s)
        return a.s > b.s;
    else return a.d < b.d;
}
int main ()
{
    int c;
    scanf ("%d", &c);
    while (c--)
    {
        int n;
        memset (v, 0, sizeof(v));
        scanf ("%d", &n);
        for (int i=0; i<n; ++i)
            scanf ("%d", &data[i].d);
        for (int i=0; i<n; ++i)
            scanf ("%d", &data[i].s);
        sort (data, data+n, cmp);
        /*for(int i=0;i<n;i++)
        {
            cout<<data[i].d<<" "<<data[i].s<<endl;
        }*/
        int a= 0;
        for (int i=0; i<n; ++i)
        {
            int j=data[i].d;
            for (; j>=1; --j)  
                if(!v[j])
                {
                    v[j] = 1;
                    break;
                }
            if(j == 0) //如果减到零还不能被安排上,那就扣分
                a+= data[i].s;
        }
        printf ("%d\n", a);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_17679843/article/details/88702789