Codeforces Global Round 14 C. Phoenix and Towers
作者:互联网
一、算法分析
刚开始容易想到dfs,但是考虑集合的个数是给定的,只需要往里面填数就行了。具体的填数策略是贪心。注意题目中的一个重要条件:每个块的高度都不会超过x。
题目要求任意两个集合的规模之差不能超过x,可以转化为只要最小的集合和最大的集合规模之差不超过x即可。用小根堆维护集合,每次把方块分配到最小的集合s_min里面,则可能出现三种情况:
1)s_min仍为最小的集合,原先|s_max|-|s_min|<=x,s_min增加之后更加不会破坏这个条件。
2)原先的s_min不是最小的集合了,但也不是最大的集合,则新的s_min在原先也满足|s_max|-|s_min|<=x。
3)原先的s_min变成了最大的集合s_max:如图所示:
二、代码
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<queue> 6 using namespace std; 7 const int N=100050; 8 typedef pair<int,int> PII; //对于block,存大小和其属于的tower,对于Tower,存其大小和编号 9 int n,m,x; 10 priority_queue<PII,vector<PII>,greater<PII> >q; 11 void clear(){ 12 while(q.size()) q.pop(); 13 } 14 int id[N]; 15 int main(){ 16 17 int T; 18 cin>>T; 19 while(T--){ 20 scanf("%d%d%d",&n,&m,&x); 21 clear(); 22 for(int i=1;i<=m;i++) q.push({0,i}); 23 for(int i=1;i<=n;i++){ 24 int w; 25 scanf("%d",&w); 26 PII t=q.top(); 27 q.pop(); 28 id[i]=t.second; 29 t.first+=w; 30 q.push(t); 31 } 32 printf("YES\n"); 33 for(int i=1;i<=n;i++){ 34 printf("%d ",id[i]); 35 } 36 printf("\n"); 37 } 38 39 40 return 0; 41 42 }
标签:14,Phoenix,min,Towers,max,int,原先,集合,include 来源: https://www.cnblogs.com/talk-sea/p/14731252.html