[Codeforces 841C]Leha and Function
阿新 • • 發佈:2017-10-19
its 得出 數列 原來 struct != using %d span
題目大意:定義函數F(n,k)為[1,2,3,..n]中k個元素的子集中最小元素的數學期望。現在給你兩個長度相等的數列A,B(A中元素嚴格大於B中元素),現在要你重新排列A,使得$\sum\limits _{i=1}^m F(A‘[i],B[i])$最大。求排完後的A‘。
解題思路:首先找規律,得出$F(n,k)=\frac{n+1}{k+1}$。
然後進行貪心,將B[i]中小的元素對應A[i]中大的元素。為什麽這樣做是對的?隨便舉四個正整數$x,y,a,b(x<y<a<b)$,比較$\frac{a+1}{x+1}+\frac{b+1}{y+1}$和$\frac{b+1}{x+1}+\frac{a+1}{y+1}$的大小即可得出。
如果沒找出規律,則可以觀察樣例,發現B[i]越小A[i]越大,則也能得出正解。
於是我們把B[i]升序排序,A[i]降序排序,然後把A‘[i]按照B[i]原來的位置排列即可。
觀察樣例發現字典序要最小,那麽我們將B[i]的位置作為第二關鍵字,越大放在越前面,即可保證字典序最小。
時間復雜度$O(n\log_2 n)$。
C++ Code:
#include<algorithm> #include<cstdio> #include<functional> using namespace std; struct B{ int num,no; bool operator <(const B& $1)const{ if(num!=$1.num) return num<$1.num; return no>$1.no; } }b[200005]; int a[200005],n,val[200005]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%d",&a[i]); for(int i=1;i<=n;++i)scanf("%d",&b[i].num),b[i].no=i; stable_sort(b+1,b+n+1); stable_sort(a+1,a+n+1,greater<int>()); for(int i=1;i<=n;++i) val[b[i].no] = a[i]; for(int i=1;i<=n;++i) printf("%d ",val[i]); return 0; }
[Codeforces 841C]Leha and Function