zoukankan      html  css  js  c++  java
  • NOI模拟(3.6)Assignment

    Description

    随机生成一个长度为m且每个元素都为1~n之间的整数的单调不下降序列 ~ (即序列的 (i>1)都不小于 ),(随机生成指每一种可能的序列都等概率被生成)。请问这个序列的众数出现次数期望是多少,有多组数据。
     

    Input

    第一行一个整数T,为数据组数
    接下来T行,每行两个被空格隔开的正整数m,n为序列长度和元素的值的上界。

    Output

    一共T行,每一行一个实数,为每组数据的答案
    如果你的答案与标准答案的误差不超过1e-5,则视为正确
     

    Sample Input

    4
    1 5
    3 3
    2 9
    9 6

    Sample Output

    1.0000000000
    2.2000000000
    1.2000000000
    4.3146853147
     

    Data Constraint

    对于10%的数据:n,m<=5,T=1
    对于另外20%的数据:m<=15,T<=5
    对于另外20%的数据:n,m<=50, T<=5
    对于100%的数据:1<=m<=250,1<=n<=1e9,T<=15
     

    Hint

    对于3 3这一组数据,有以下情况(x为众数出现的次数)
    1 1 1 (x = 3) 
    1 1 2 (x = 2) 
    1 1 3 (x = 2) 
    1 2 2 (x = 2) 
    1 2 3 (x = 1) 
    1 3 3 (x = 2) 
    2 2 2 (x = 3) 
    2 2 3 (x = 2) 
    2 3 3 (x = 2) 
    3 3 3 (x = 3) 
    所以期望是1/10+2*6/10+3*3/10=22/10

    Solution

    看看应该是一道dp

    可以有这样一个思路

    令f(i,j)为构造出的序列长度为i,当前填入序列第j种数,为了限制众数的出现次数,要去除所有众数出现次数大于限定的情况

    因此,f(k,i,j)=f(k,i-1,j-1)+f(k,i-1,j)-f(k,i-k-1,j-1),其中k代表限定众数出现次数为k

    最后乘上一个组合数就是答案了

    #include <stdio.h>
    #include <string.h>
    
    template<class T> inline void read(T &x)
    	{
    	int c=getchar();
    	for(x=0;c<48||c>57;c=getchar());
    	for(;c>47&&c<58;c=getchar())x=(x<<1)+(x<<3)+c-48;
    	}
    
    int T,m,n;
    long double C[255],f[255][255][255],g[255],ans;
    
    int main()
    	{
    	freopen("assignment.in","r",stdin);
    	freopen("assignment.out","w",stdout);
    	for(int k=1;k<=250;k++)
    		{
    		f[k][0][0]=1;
    		for(int i=1;i<=250;i++)
    			for(int j=1;j<=i;j++)
    				{
    				f[k][i][j]=f[k][i-1][j-1]+f[k][i-1][j];
    				if(i-k-1>=0)f[k][i][j]-=f[k][i-k-1][j-1];
    				}
    		}
    	for(read(T);T;T--)
    		{
    		read(m),read(n);
    		C[0]=1;
    		for(int i=1;i<=m;i++)
    			C[i]=C[i-1]*(n-i+1)/i;
    		for(int k=1;k<=m;k++)
    			{
    			g[k]=0;
    			for(int j=1;j<=m;j++)
    				g[k]+=f[k][m][j]*C[j];
    			}
    		ans=0;
    		for(int k=1;k<=m;k++)
    			ans+=k*(g[k]-g[k-1])/g[m];
    		printf("%.6f
    ",(double)ans);
    		}
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    	}
    

      

  • 相关阅读:
    系统实践2-2:查看dockerfile-032092135mysql容器的配置信息
    系统综合实践1
    SDN——实验脚本7-2:hardtimeout.json
    SDN——实验脚本7-1:odlnorth.py
    实验 7:OpenDaylight 实验——Python 中的 REST API 调用
    预习非数值数据的编码方式
    预习原码补码
    C语言ll作业01
    C语言寒假大作战04
    C语言寒假大作战03
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6520469.html
Copyright © 2011-2022 走看看