学习贪心ing,set的初学

来源:互联网 发布:淘宝充值中心 靠谱 编辑:程序博客网 时间:2024/06/07 08:07

/*题意:原本有n个航班,他们的起飞时间是1-n,
现在机场规定在每一天的前k分钟不能有飞机起飞,那么就得有航班起飞要延误,
现在给出每个航班延误一分钟所消耗的费用,
问你怎么安排飞机的起飞才能使花费最少,飞机起飞时间不能比原本的要早。

set的特性是所有元素都会根据元素的键值自动排序,set不允许两个元素拥有相同的键值*/
//代码:
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long

using namespace std;


struct node
{
    int d,c;
};
//id是正常时的顺序,c是每次的航班延迟带来的损耗
node a[300010];

bool cmp(node a,node b)
{
    if(a.c == b.c)
        return a.d > b.d;
    return a.c > b.c;
}//排序规则

int ans[300010];
set<int> s;//set是int型的
int main()
{
    int n,k,i,j;
    while(scanf("%d%d",&n,&k)==2){//输入n,k(scanf的返回值是输入值的个数)
   
        for(i=1;i<=n;i++)
        {
            cin>>a[i].c;
            a[i].d = i;
            s.insert(k+i);//把"耽搁之后航班离开的时间 "放入set
        }
        sort(a+1,a+1+n,cmp);
        LL sum = 0;
        for(i=1;i<=n;i++)
        {
            int p = *s.upper_bound(a[i].d-1);//upper_bound返回第一个>()里面的数的指针
            //减去1,就可以找>=a[i].id的数了
   
            
            ans[a[i].d] = p;//把每个p和id对应起来
 
            sum += (LL)(p-a[i].d)*a[i].c;
            s.erase(p);
        }
        printf("%I64d\n",sum);//输出sum,sum是long long型
        for(i=1;i<=n;i++)
            printf("%d ",ans[i]);
        cout<<endl;
    }

    return 0;
}
//用贪心的思想,延误花费大的肯定要放到前面,而且又不能比原本的时间早,
//所以把都延迟k分钟的时间都放到了set里,
//然后每次找不小于原本时间的第一小的时间,就能保证花费最小。