首页 > 代码库 > NOI模拟(3.6)Assignment
NOI模拟(3.6)Assignment
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\n",(double)ans); } fclose(stdin); fclose(stdout); return 0; }
NOI模拟(3.6)Assignment
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。