cf840A Leha and function

本文介绍了一种通过重新排列数组M并结合数组N来最大化特定函数F(M',N)之和的问题。函数F(a,b)涉及集合A及其子集B的最小值期望。文章提供了样例输入输出,并详细解析了函数F的数学期望公式,最后给出了解决方案的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哇这个意义不明的公告……欺负英语水平差的人不会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 200010
struct 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的日子何时才是一个尽头啊……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值