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;
}

浙公网安备 33010602011771号