THUSC2011 TS A1295 Necklace
因为要去THUSC了做一下以前THUSC的题、、
这个题是一个比较明显的概率DP、、
可以把状态用当前是第几个珠子、到目前为止的最长长度范围、当前珠子颜色表示、
具体点就是f[i][j][k]表示前i个珠子、最长长度不超过j、最后一个珠子的颜色是k的概率
那么f[i][j][k]=sigma(f[i-1][j][*])*p[i][k]-sigma(f[i-j-1][j][*!=k])*P(i-j..i的颜色都为k)
最后一个P可以在N^2的时间内预处理出来、、然后两个sigma的东西可以单独存出来加速、
Code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <vector> #include <set> #include <map> #include <queue> #define ps system("pause") #define message printf("*\n") #define pb push_back #define X first #define Y second #define PII pair<int,int> #define rep(a,b,c) for(int a=b;a<=c;a++) #define per(a,b,c) for(int a=b;a>=c;a--) typedef long long ll; using namespace std; int n,m; double sp[1010][11],p[1010][1010][11],f[1010][1010][11],s[1010][1010]; double ans=0; int main(){ scanf("%d%d",&n,&m); rep(i,1,n) rep(j,1,m) scanf("%lf",&sp[i][j]); rep(i,1,n) rep(k,1,m) p[i][i][k]=sp[i][k]; rep(d,1,n-1) rep(i,1,n) if (i+d<=n) rep(k,1,m) p[i][i+d][k]=p[i][i+d-1][k]*p[i+d][i+d][k]; rep(j,0,n) s[0][j]=1; rep(i,1,n) rep(j,1,n) rep(k,1,m){ f[i][j][k]=s[i-1][j]*p[i][i][k]-((i>j)?((s[i-j-1][j]-f[i-j-1][j][k])*p[i-j][i][k]):(0)); s[i][j]+=f[i][j][k]; } //rep(i,1,n) rep(j,1,i) rep(k,1,m) printf("%d %d %d:%.6lf\n",i,j,k,f[i][j][k]); rep(i,1,n) ans+=(s[n][i]-s[n][i-1])*i; printf("%.6lf\n",ans); return 0; }