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\n",sum); printf("%d",idx[1]); for(int i=2;i<=n;i++) printf(" %d",idx[i]); printf("\n"); } 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\n%d",sum,ans[1]); for(int i=2;i<=n;i++) printf(" %d",ans[i]); printf("\n"); } return 0; }