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

  

posted @ 2013-06-10 17:16  JS_Shining  阅读(311)  评论(1编辑  收藏  举报