codeforces round 433 C. Planning 贪心

题目大意:

输入n,k,代表n列航班,初始始发实践为1,2,3分钟以此类推,然后输入n个整数分别代表延迟1分钟第i个航班损失多少钱,然后调整后的始发时间表是这样的,任何一辆航班的始发时间不能在他的初始始发实践之前而且满足k+1<=ti<=k+n,然后,让你输出最小的损失以及一次输出每辆航班的始发时间;

基本思路:

一开始我的思路是肯定是让每分钟损失最多的放在前面,然后由于还有限制条件所以,如果当前位置(时间)不能满足,那就向后找位置,但是这样是对于一个航班找时间,时间复杂度是n^2的,果断超时;

后来参考了同学代码,是对于一个时间,用一个优先队列处理能放在当前时间的拥有每分钟最大损失的航班,这样只需要n*logn的复杂度,涨思路;

反思与总结:

其实仔细想想,就是一个萝卜一个坑,萝卜和坑的个数都是一定的,到底是拿着萝卜去找坑,还是挖坑去埋哪一个萝卜,在限制条件不同的时候,会有不同的时间复杂度;

代码如下:

(超时代码)

#include<bits/stdc++.h>

using namespace std;

#define rep(a,b,c) for(int (a)=(b);(a)<=(c);(a++))
#define drep(a,b,c) for(int (a)=(b);(a)>=(c);(a--))
#define mst(ans,false) memset(ans,0,sizeof(ans))
#define mkp make_pair

typedef long long int ll;
typedef long double lb;
typedef pair<int,int> pii;
const int dx[]={-1,0,0,1};
const int dy[]={0,-1,1,0};

const int maxn = 300000+10;
struct Node
{
    int id,val;
    bool operator<(const Node& a)const
    {
        if(val==a.val) return id<a.id;
        return val>a.val;
    }
}node[maxn];
int vis[maxn*2];
int idx[maxn];
int n,k;
int main()
{
    while(scanf("%d%d",&n,&k)==2)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&node[i].val);
            node[i].id=i;
        }
        sort(node+1,node+n+1);
        int t=k+n;
        for(int i=k+1;i<=k+n;i++) vis[i]=0;
        int pos=k+1;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            int tt=node[i].id;
            if(tt>=pos)
            {
                for(int j=tt;j<=t;j++)
                {
                    if(vis[j]!=0) continue;
                    vis[j]=1;
                    idx[node[i].id]=j;
                    sum+=(j-node[i].id)*node[i].val;
                    break;
                }

            }
            else
            {

                for(int j=pos;j<=t;j++)
                {
                    if(vis[j]!=0) continue;
                    vis[j]=1;
                    idx[node[i].id]=j;
                    sum+=(j-node[i].id)*node[i].val;
                    break;
                }
            }
        }
        printf("%I64d
",sum);
        printf("%d",idx[1]);
        for(int i=2;i<=n;i++) printf(" %d",idx[i]);
        printf("
");
    }
    return 0;
}

(ac代码)

#include<bits/stdc++.h>

using namespace std;

const int maxn = 300000+10;
typedef long long ll;

int ans[maxn];
struct Node
{
    ll x;
    int id;
    bool operator<(const Node& a)const {return x<a.x;}
}node[maxn];
priority_queue<Node>pq;

int main()
{
    int n,k;
    ll sum;
    while(scanf("%d%d",&n,&k)==2)
    {
        sum=0;
        while(!pq.empty()) pq.pop();
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d",&node[i].x);
            node[i].id=i;
            if(i<=k) pq.push(node[i]);
        }
        for(int i=k+1;i<=n;i++)
        {
            pq.push(node[i]);
            Node t=pq.top();
            pq.pop();
            sum+=(i-t.id)*t.x;
            ans[t.id]=i;
        }
        for(int i=1;i<=k;i++)
        {
            Node t=pq.top();
            pq.pop();
            sum+=(i+n-t.id)*t.x;
            ans[t.id]=i+n;
        }
        printf("%I64d
%d",sum,ans[1]);
        for(int i=2;i<=n;i++) printf(" %d",ans[i]);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/imzscilovecode/p/7490491.html