2019.01.27-bzoj2510: 弱题
题目描述:
有M个球,一开始每个球均有一个初始标号,标号范围为1~N且为整数,标号为i的球有ai个,并保证Σai = M。
每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个球标号为k(k < N),则将它重新标号为k + 1;若这个球标号为N,则将其重标号为1。(取出球后并不将其丢弃)
现在你需要求出,经过K次这样的操作后,每个标号的球的期望个数。
算法标签:矩阵优化dp
网上题解太多了,懒得搞图...懒惰使我退缩
以下代码:
#include<bits/stdc++.h> #define il inline #define db double #define _(d) while(d(isdigit(ch=getchar()))) using namespace std; const int N=1e3+5; int n,m,k; struct mat{ db f[N]; }a,b; il int read(){ int x,f=1;char ch; _(!)ch=='-'?f=-1:f;x=ch^48; _()x=(x<<1)+(x<<3)+(ch^48); return f*x; } il mat C(mat x,mat y){ mat z;for(int i=1;i<=n;i++)z.f[i]=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ z.f[i]+=x.f[j]*(y.f[(i-j+n)%n+1]); } } return z; } int main() { n=read();m=read();k=read(); for(int i=1;i<=n;i++)a.f[i]=read(); if(n==1){printf("%.3lf",1.0*m);return 0;} b.f[1]=1.0-1.0/(db)m;b.f[2]=1.0/(db)m; while(k){ if(k&1)a=C(a,b); b=C(b,b);k>>=1; } for(int i=1;i<=n;i++)printf("%.3lf\n",a.f[i]); return 0; }