codeforces - 723C 题解
Posted 远见望远
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces - 723C 题解相关的知识,希望对你有一定的参考价值。
题目大意是:给定一个歌曲演唱的序列,第i个数字代表第i首歌由ai号乐队演唱;问如何用最少的操作将这些歌改成1-m号乐队演唱,且每个乐队演唱歌曲数的最小值最大。
问题解法:首先分析如何让最小值最大,有两种方式来提升最小值,第一种是将1-m范围外的乐队演唱的歌分给1-m范围内的演唱数最小的乐队,第二种是将1-m内演唱数较大的乐队的歌分一些给1-m内演唱数较小的乐队。所以题目的贪心策略也就基本确定了
1 #include<iostream> 2 #include<algorithm> 3 #include<climits> 4 using namespace std; 5 int a[10001]; 6 int b[10001]={}; 7 int n,m; 8 int board; 9 bool check() 10 { 11 for(int i=1;i<=m;i++) 12 { 13 if(b[i]<board) 14 { 15 return true; 16 } 17 } 18 return false; 19 } 20 int main() 21 { 22 cin>>n>>m; 23 for(int i=1;i<=n;i++) 24 { 25 cin>>a[i]; 26 if(a[i]<=m) 27 { 28 b[a[i]]+=1; 29 } 30 } 31 int res1,res2=0; 32 board=n/m; 33 for(int i=1;i<=n;i++) 34 { 35 if(a[i]>m) 36 { 37 for(int j=1;j<=m;j++) 38 { 39 if(b[j]<n/m) 40 { 41 b[j]+=1; 42 a[i]=j; 43 res2+=1; 44 break; 45 } 46 } 47 } 48 } 49 while(check()) 50 { 51 for(int i=1;i<=n;i++) 52 { 53 if(b[i]>board) 54 { 55 for(int j=1;j<=m;j++) 56 { 57 if(b[j]<board) 58 { 59 for(int k=1;k<=n;k++) 60 { 61 if(a[k]==i) 62 { 63 a[k]=j; 64 b[i]-=1; 65 b[j]+=1; 66 res2+=1; 67 break; 68 } 69 } 70 if(b[i]<=board) 71 { 72 break; 73 } 74 } 75 } 76 } 77 } 78 } 79 res1=INT_MAX; 80 for(int i=1;i<=m;i++) 81 { 82 res1=min(res1,b[i]); 83 } 84 cout<<res1<<" "<<res2<<endl; 85 for(int i=1;i<=n;i++) 86 { 87 cout<<a[i]<<" "; 88 } 89 return 0; 90 }
以上是关于codeforces - 723C 题解的主要内容,如果未能解决你的问题,请参考以下文章