• CF1153F Serval and Bonus Problem


    Serval and Bonus Problem

    给⼀个⻓度为 (l) 的线段,随机选了 (n) 条⼦线段,求被覆盖了至少 (k) 次的期望⻓度。

    (1≤k≤n≤2000)

    计数DP

    https://jkloverdcoi.github.io/2019/04/16/CF1153/

    随便在线段上钦定 (2n) 个点,分割成 (2n+1) 段区间,所以每段区间的期望长度就是 (frac l {2n+1})。于是只需要再乘上一段区间至少被 (k) 条线段覆盖的概率就好了。

    (f(i,j)) 表示考虑 (i) 个端点,第 (i) 个端点后面的区间恰好被 (j) 条线段所覆盖的方案数。转移时枚举 (i) 是作为左端点还是右端点,(O(n^2)) 大力转移。

    最后将所有合法方案数目求和,除以 (f(2n,0)) 得到概率。

    统计答案时枚举各个区间的贡献,注意两边的DP组合起来的时候需要乘以 (j!),表示线段端点的对应关系。

    CO int N=4000+10;
    int fac[N];
    int dp[N][N];
     
    int main(){
    	int n=read<int>(),K=read<int>(),L=read<int>();
    	L=mul(L,fpow(2*n+1,mod-2));
    	fac[0]=1;
    	for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
    	dp[0][0]=1;
    	for(int i=0;i<2*n;++i)
    		for(int j=n<i?n:i;j>=0;--j){
    			dp[i+1][j+1]=add(dp[i+1][j+1],dp[i][j]);
    			if(j) dp[i+1][j-1]=add(dp[i+1][j-1],mul(dp[i][j],j));
    		}
    	int ans=0;
    	for(int i=1;i<2*n;++i)
    		for(int j=K;j<=n;++j){
    			int sum=mul(dp[i][j],dp[2*n-i][j]);
    			sum=mul(sum,fac[j]); // corresponding relationship
    			ans=add(ans,sum);
    		}
    	ans=mul(ans,mul(L,fpow(dp[2*n][0],mod-2)));
    	printf("%d
    ",ans);
    	return 0;
    }
    

    微积分

    从另一种角度考虑,恰好 (k) 次的期望长度为

    [l imes int_0^1 (2x(1-x))^k (1-2x(1-x))^{n-k} dx ]

    (k)(→k+1) 次只需要乘上一个二次的,除以一个二次的。每次直接积分即可。

    我发现积分的结果还要乘上 (inom{n}{k}),这可能是因为线段其实是有放入的先后顺序的,即可以把它看成有标号的。

    DP的做法应该是钦定了放入顺序就是从左到右。

    poly operator*(CO poly&a,CO poly&b){
    	int n=a.size()-1,m=b.size()-1;
    	poly ans(n+m+1);
    	for(int i=0;i<=n;++i)for(int j=0;j<=m;++j)
    		ans[i+j]=add(ans[i+j],mul(a[i],b[j]));
    	return ans;
    }
    poly operator/(poly a,CO poly&b){
    	int n=a.size()-1,m=b.size()-1;
    	poly ans(n-m+1);
    	for(int i=n;i>=m;--i)if(a[i]){
    		ans[i-m]=mul(a[i],fpow(b[m],mod-2));
    		for(int j=i;j>=i-m;--j) a[j]=add(a[j],mod-mul(ans[i-m],b[j-(i-m)]));
    	}
    	return ans;
    }
    
    CO int N=4000+10;
    int inv[N];
    
    poly inter(CO poly&a){
    	int n=a.size()-1;
    	poly ans(n+2);
    	for(int i=1;i<=n+1;++i) ans[i]=mul(a[i-1],inv[i]);
    	return ans;
    }
    int calc(CO poly&a,int x){
    	int n=a.size()-1,ans=0;
    	for(int i=n;i>=0;--i) ans=add(mul(ans,x),a[i]);
    	return ans;
    }
    
    CO poly a=(poly){0,2,mod-2},b=(poly){1,mod-2,2};
    int fac[N],ifac[N];
    
    IN int binom(int n,int m){
    	return mul(fac[n],mul(ifac[m],ifac[n-m]));
    }
    int main(){
    //	freopen("CF1153F.in","r",stdin);
    	int n=read<int>();
    	inv[0]=inv[1]=1;
    	for(int i=2;i<=2*n+1;++i) inv[i]=mul(mod-mod/i,inv[mod%i]);
    	fac[0]=1;
    	for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
    	ifac[n]=fpow(fac[n],mod-2);
    	for(int i=n-1;i>=0;--i) ifac[i]=mul(ifac[i+1],i+1);
    	int K=read<int>(),L=read<int>();
    	poly f=(poly){1};
    	for(int i=1;i<=K;++i) f=f*a;
    	for(int i=1;i<=n-K;++i) f=f*b;
    	int ans=0;
    	for(int i=K;i<=n;++i){
    		poly g=inter(f);
    		ans=add(ans,mul(calc(g,1),binom(n,i)));
    		f=f/b*a;
    	}
    	ans=mul(ans,L);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    很遗憾我的代码会TLE。

  • 相关阅读:
    Swagger UI教程 API 文档神器 搭配Node使用 web api 接口文档 (转)
    C#测试web服务是否可用(转)
    使用Fiddler测试WebApi接口
    .Net 序列化(去除默认命名空间,添加编码)
    Win10 下Cisco AnyConnect Secure Mobility Client问题(转)
    jQuery.extend 函数详解(转)
    Oracle 取Group By 第一条
    EFProf用法
    c#和JS数据加密(转)
    C#中字符数组,字节数组和string之间的转化(转)
  • 原文地址:https://www.cnblogs.com/autoint/p/12106146.html
Copyright © 2020-2023  润新知