• [Codeforces 841C]Leha and Function


    题目大意:定义函数F(n,k)为[1,2,3,..n]中k个元素的子集中最小元素的数学期望。现在给你两个长度相等的数列A,B(A中元素严格大于B中元素),现在要你重新排列A,使得$sumlimits _{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(nlog_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;
    } 
    
  • 相关阅读:
    djano框架根据小牛深入研究
    python raise 是啥东西
    python调request报错
    python当前时间,时间偏移
    写好了,定时任务,怎么让定时任务,去在服务器上跑?
    python实现定时任务-目的解决自动化造数据
    django-celery
    Fruits【水果】
    The Extinction of Some Languages【一些语言的消失】
    Dawson City【道森市】
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7691427.html
Copyright © 2020-2023  润新知