zoukankan      html  css  js  c++  java
  • CF1096E The Top Scorer

    题目传送门:CF1096E

    洛谷入口

    题目大意:

    (p个人,每个人有得分a_i)
    (总得分∑a_i=s)
    (第一个人得分a_1≥r)
    (得分最高的人可以获胜,如果多个人得分最高,则等概率随机其中一个人获胜)
    (问第一个人获胜的概率(运算皆对998244353取模))

    数据范围

    (circ) (1le ple100)
    (circ) (0le rle sle5000)

    题解

    这题算概率,就是获胜方案数除以总情况数
    那要求获胜方案数就可以试着去(DP)
    首先就先枚举获胜者的分数,假设为(i)
    接下来再假设有(j)个人都是这个分数(i)(包含此获胜者)
    那么剩余人还有(p-j)
    剩余分数还有(s-i imes j)
    而且这些人分数都不到(i)
    剩余的人分一些分简单,但如何让每个人得分都不超过(i)呢?
    其实可以用容斥的思想做一下
    我们先考虑至少(0)人超过要求的方案数
    再减去至少(1)人的方案数
    会发现减多了,于是再加回至少(2)人的方案数
    …………………………
    最后就加上((-1)^i imes)至少p-j人方案数
    那对于至少(x)人,要求其超过(lim-1)的求法:
    先给这(x)人每人分个(lim)的分数
    然后再按照隔板法来分(要选其中元素可为(0)的方法)
    这样就可以算出一个通式:
    ((-1)^x imes C_p^x imes C^{p-1}_{s-lim imes x+p-1})
    (i)再按照(0)((p-j))枚举即可解决对于问题(Q(总个数s,总人数p,限制lim))的方案数
    那把这个套进去大的轮廓会得到答案求法:
    (sumlimits^{s}_{i=r}sumlimits^{p}_{j=1}Q(s-i imes j,p-j,i) imes C^{j-1}_{p-1}/j)
    其实理解到这,总情况求法肯定都没问题了吧
    就是(C^{p-1}_{s-r+p-1})
    那么解题步骤就这些
    式子没啥进一步推的,这个复杂度就可以过了

    注意事项

    建议把所有范围内的组合数都求一遍
    ①.组合数递推式是一个公式(其实可以用实际问题的方式轻松证明)
    (C^{j}_{i}=C^{j}_{i-1}+C^{j-1}_{i-1})
    注意初始化(C^0_i都为1)

    ②.逆元的线性求法有一个公式
    (inv_i=mod-(mod/i) imes inv_{mod\%i}\%mod)
    初始化的话记得加个(inv_1=1)

    ③.最后除以总情况时最好用个费马小定理解决
    (说到费马小定理就别忘了带上快速幂)

    好了就这些了好像挺多的,下面上代码!↓↓↓

    AC代码

    #include<bits/stdc++.h>
    #define maxn 5200
    #define int  long long//懒的表现
    using namespace std;
    int mod=998244353,inv[maxn],c[maxn+10][maxn+10],p,s,r,ans;//懒*2
    void init(){//初始化inv&&c
    	inv[1]=1;
    	for(int i=2;i<=p;i++)inv[i]=mod-(mod/i)*inv[mod%i]%mod;
    	c[0][0]=1;
    	for(int i=1;i<=maxn;i++){
    		c[0][i]=1;
    		for(int j=1;j<=i;j++)c[j][i]=(c[j][i-1]+c[j-1][i-1])%mod;
    	}
    }
    int ksm(int x,int y){
    	int tot=1,tmp=x;
    	while(y){
    		if(y&1)tot=tot*tmp%mod;
    		tmp=tmp*tmp%mod;
    		y>>=1;
    	}
    	return tot;
    }
    int C(int a,int b){//为了谨慎而存在
    	if(a>b||a<0||b<0)return 0;
    	return c[a][b];
    }
    int jj(int sum,int x,int lim){
    	if(sum==0)return 1;
    	if(sum<0)return 0;
    	int tot=0;
    	for(int i=0;i<=x;i++)tot=(tot+((i&1)?998244352:1)*c[i][x]%mod*C(x-1,sum-i*lim+x-1))%mod;
    	return tot;
    }
    signed main(){
    	cin>>p>>s>>r;
    	init();
    	for(int i=r;i<=s;i++){
    		for(int j=1;j<=p;j++){
    			if((p-j)*(i-1)+i*j<s)continue;
    			ans=(ans+jj(s-i*j,p-j,i)*C(j-1,p-1)%mod*inv[j])%mod;
    		}
    	}
    	cout<<ans*ksm(c[p-1][s-r+p-1],mod-2)%mod;
    }
    

    编辑不易,支持一下吧,关注,点赞,评论都好!

    THE END

    Reality&Imagine
  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/yang-RA-NOI/p/12594003.html
Copyright © 2011-2022 走看看