【CodeForces】841C. Leha and Function(Codeforces Round #429 (Div. 2))

【题意】定义函数F(n,k)为1~n的集合中选择k个数字,其中最小数字的期望

给定两个数字集A,B,A中任意数字>=B中任意数字,要求重组A使得对于i=1~n,sigma(F(Ai,Bi))最大。

【算法】数学结论+数学期望+排序

【题解】很无奈,这题放在div2 C,难以推导的期望公式,广为人知的结论,容易观察样例得出的做法,都体现了这道题的不合理性。

F(n,k)=(n+1)/(k+1)

公式推导可能触及我的知识盲区了QAQ

得到公式后,显然要求k尽可能小,n尽可能大,经验告诉我们随着两数差增大,两数相除的结果急速增大(相对的,两数差减小,两数相乘的结果急速增大)。

所以排序后反着相对就可以了,而这个结论可以通过观察样例很快得出。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int read()
{
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=200010;

int n,a[maxn],c[maxn];
struct cyc{int num,ord;}b[maxn];
bool cmp(cyc a,cyc b)
{return a.num<b.num;}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=n;i++){
        b[i].num=read();
        b[i].ord=i;
    }
    sort(b+1,b+n+1,cmp);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)c[b[i].ord]=a[n-i+1];
    for(int i=1;i<=n;i++)printf("%d ",c[i]);
    return 0;
}
View Code

 

posted @ 2017-08-23 12:20  ONION_CYC  阅读(206)  评论(0编辑  收藏  举报