【数学】组合数学和期望

ll A(ll a, ll b)
{//求排列数
	ll ret = 1;
	for (ll i = 1; i <= b; i++)
	{
		ret = ret * (a - i + 1) % MOD;
	}
	return ret;
}
int qmi(int a, int k, int p)
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = (ll)res * a % p;
        a = (ll)a * a % p;
        k >>= 1;
    }
    return res;
}
ll C(ll a,ll b){
 if (b > a) return 0;

    ll res = 1;
for (ll i = 1, j = a; i <= b; i ++, j -- )
    {
        res = res * j % p;
        res = res * qmi(i, p - 2, p) % p;
    }
return res;
}

积累trick

Station of Fate

Problem - L - Codeforces

There are nn people standing in mm stations, forming mm queues.

You don't know which person is in which station, or in what order they are standing in queue, so you want to count the number of different schemes. Two schemes are considered different, if and only if there exists a station whose queue consists of different people, or has different orders.

Calculate the number of different schemes modulo 998244353998244353.

Input

The first line contains an integer TT (1≤T≤1001≤T≤100), denoting the number of test cases. Then TT test cases follow.

Each test case contains a single line containing two integers n,mn,m (1≤m≤n≤1051≤m≤n≤105).

Output

For each test case, output the number of different schemes modulo 998244353998244353.

#include<iostream>
using namespace std;
#define ll long long
const ll p=998244353;
int qmi(int a, int k, int p)
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = (ll)res * a % p;
        a = (ll)a * a % p;
        k >>= 1;
    }
    return res;
}
ll C(ll a,ll b){
 if (b > a) return 0;

    ll res = 1;
for (ll i = 1, j = a; i <= b; i ++, j -- )
    {
        res = res * j % p;
        res = res * qmi(i, p - 2, p) % p;
    }
return res;
}

int main(){
int T;cin>>T;
while(T--){
int n,m;cin>>n>>m;
ll res=C(n,m)%p;
res=(res*m)%p;
for(ll i=1;i<=n-1;i++){
    res=(res*i)%p;
}
cout<<res<<endl;
}

}

5277. 三元组

5277. 三元组 - AcWing题库

给定一个长度为 nn 的正整数数组 a1,a2,…,ana1,a2,…,an。

请你计算,一共有多少个三元组 (i,j,k)(i,j,k)(1≤i<j<k≤n1≤i<j<k≤n),使得 ai⋅aj⋅akai⋅aj⋅ak 为最小可能值。

输入格式

第一行包含整数 nn。

第二行包含 nn 个正整数 a1,a2,…,ana1,a2,…,an。

输出格式

一个整数,表示满足条件的三元组的数量。

数据范围

前 33 个测试点满足,3≤n≤63≤n≤6。
所有测试点满足,3≤n≤1053≤n≤105,1≤ai≤1091≤ai≤109。

输入样例1:

4
1 1 1 1

输出样例1:

4

输入样例2:

5
1 3 2 3 4

输出样例2:

2

输入样例3:

6
1 3 3 1 3 2

输出样例3:

1
#include<iostream>
using namespace std;
#include<algorithm>
#define ll long long
const ll N=100010;
ll n;
ll a[N];
ll C(ll a,ll b){
   ll res=1;
   for(ll i=a,j=1;j<=b;i--,j++){
       res=res*i/j;
   }
   return res;
}

int  main(){
    cin>>n;
    for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
    sort(a+1,a+n+1);

    ll k=a[3];
    //ll st=3;while(st>=1&&a[st]==a[3])st--;st++;
    //ll ed=3;while(ed<=n&&a[ed]==a[3])ed++;ed--;
    ll st=lower_bound(a+1,a+n+1,a[3])-a;
    ll ed=upper_bound(a+1,a+n+1,a[3])-a;ed--;
    ll x=3-st+1;ll y=ed-st+1;
    cout<<C(y,x);

}

贝茜开车

6094. 贝茜开车 - AcWing题库

贝茜是哞哞出行平台的司机,她的日常工作是送约翰家的奶牛们前往牧场。

她的汽车的最大载客重量为 pp。

约翰家一共有 nn 头奶牛,编号 1∼n1∼n,其中第 ii 头奶牛的重量为 aiai。

在准备上车前,奶牛们会按某种顺序排成一队,然后按顺序依次上车。

当轮到一头奶牛上车时,如果该奶牛上车会导致超重(即所有上车奶牛的总重量大于 pp),贝茜就会直接声称车已坐满,并谢绝该奶牛以及其后面的所有奶牛上车。(注意,在这种情况下,为了避免该奶牛心里不平衡向平台举报自己,即便后面有更轻的奶牛可以上车,贝茜也不会招待。)

已知,奶牛们的排队顺序是完全随机的,也就是说,n!n! 种排列顺序均有可能。

请你计算并输出,贝茜能够接待的奶牛数量的数学期望。

输入格式

第一行包含整数 nn。

第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an。

第三行包含整数 pp。

输出格式

输出一个实数,表示答案。

只要输出答案与标准答案的绝对或相对误差不超过 10−410−4,即视为正确。

数据范围

前 33 个测试点满足 1≤n≤101≤n≤10。
所有测试点满足 1≤n≤501≤n≤50,1≤ai≤501≤ai≤50,1≤p≤501≤p≤50。

输入样例:

3
1 2 3
3

输出样例:

1.3333333333
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 55;

int n, m;
int w[N];
LL f[N][N];

LL C(int a, int b)
{
    LL res = 1;
    for (int i = a, j = 1; j <= b; i --, j ++ )
        res = res * i / j;
    return res;
}

int main()
{
    scanf("%d", &n);
    int sum = 0;
    for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]), sum += w[i];
    scanf("%d", &m);

    if (sum <= m)
    {
        printf("%d\n", n);
        return 0;
    }

    double res = 0;
    for (int c = 1; c <= n; c ++ )
    {
        memset(f, 0, sizeof f);
        f[0][0] = 1;
        for (int i = 1; i <= n; i ++ )
            if (i != c)
                for (int j = i; j; j -- )
                    for (int k = m; k >= w[i]; k -- )
                        f[j][k] += f[j - 1][k - w[i]];

        for (int j = 0; j < n; j ++ )
            for (int k = max(m + 1 - w[c], 0); k <= m; k ++ )
                res += (double)f[j][k] / C(n - 1, j) / n * j;
    }

    printf("%lf\n", res);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值