cf840A Leha and function

来源:互联网 发布:cf积分刷枪软件 编辑:程序博客网 时间:2024/06/05 05:52

哇这个意义不明的公告……欺负英语水平差的人不会any是吧……


题意:
有一个函数F(a,b),其定义如下:
集合A为{1,2,3,…,n},集合B为A中所有元素个数为b的子集。F(a,b)表示的是B中所有集合的最小值的期望。
例如,F(4,2)表示,A={1,2,3,4},B={{1,2},{1,3},{1,4},{2,3},{2,4},{3,4}},因此,B中的最小值的期望就是1*12+2*13+3*16=1.66667
但是Leha是个无聊的人,他不满足于求这个值。现在有两个数组M,N,满足i,jMi>=Nj。现在,请你重新排列M数组变为M’,使得F(Mi,Ni)取得最大值。

样例:(先埋个伏笔)
input:
5
7 3 5 3 4
2 1 3 2 3
output:
4 7 3 5 3

input:
7
4 6 5 8 8 2 6
2 1 2 2 1 1 2
output:
2 6 4 5 8 8 6


虽然说什么最小值的最大值要带二分,不过这道题和二分大概毫无干系。
不过如果二分不了的话,又不像是数论,我们不妨先来看看能不能贪一把。

对函数F分析。如F(4,2),在对{1,2,3,4}操作时,包含1的二元组有C13=3个,除此外包含2的二元组有C12=2个,除此外包含3的二元组有C11=1个。
不妨做些拓展,对F(n,k),包含1的k元组有Ck1n1,除此外包含2的k元组有Ck1n2个,以此类推,包含n-k+1的k元组应当有Ck1nk+1=1个。
所以要求的数学期望就是
ki=1iCk1niCkn
这东西我是不会化简,有位神犇化简出来结果是这样的:(n+1)(nk)(k+1)(k+2)
显然我们让n尽可能大,让k尽可能小就行了。

但是很显然,这东西不太好化简,所以我们不妨来猜想一下。
在一串数中,期望越大就是想让最大比较大的项比较多。怎么做呢?显然n比较大且k比较小的时候,就能保证更大的最大项。至于这个猜想对不对呢?看看样例,好像是对的,别犹豫,写吧。

当然,我觉得最简单的方法还是:看看样例,凭着敏感和猜测,发现要让k最小的一项对应n最大的一项,嗯。


实现的话开个结构体存一下值和次序然后带快排即可。

#include <bits/stdc++.h>using namespace std;#define MAXN 200010struct node{    int id;    int value;}v[MAXN];int a[MAXN],b[MAXN];bool cmp1(int x,int y){    return x>y;}bool cmp2(node x,node y){    return x.value<y.value;}int main(){    int k;    cin>>k;    for(int i=1;i<=k;++i)        cin>>a[i];    sort(a+1,a+k+1,cmp1);    for(int i=1;i<=k;++i){        v[i].id=i;        cin>>v[i].value;    }    sort(v+1,v+k+1,cmp2);    for(int i=1;i<=k;++i){        b[v[i].id]=a[i];    }    for(int i=1;i<=k;++i)        cout<<b[i]<<" ";    return 0;} 

pupil的日子何时才是一个尽头啊……

原创粉丝点击