[TyvjP1519] 博彩游戏(AC自动机 + DP)

传送门

 

和bzoj1030一个德性

 

#include <queue>
#include <cstdio>
#include <cstring>
#define N 500001
#define LL long long

int m, n, r, cnt;
LL f[61][N], ans, sum = 1;
int next[N][10], fail[N];
bool val[N];
char s[N];
std::queue <int> q;

inline void insert()
{
	int i, x, now = 0, len = strlen(s + 1);
	for(i = 1; i <= len; i++)
	{
		x = s[i] - '0';
		if(!next[now][x])
			next[now][x] = ++cnt;
		now = next[now][x];
	}
	val[now] = 1;
}

inline void make_fail()
{
	int i, now;
	for(i = 1; i <= r; i++)
		if(next[0][i])
			q.push(next[0][i]);
	while(!q.empty())
	{
		now = q.front();
		q.pop();
		for(i = 1; i <= r; i++)
		{
			if(!next[now][i])
			{
				next[now][i] = next[fail[now]][i];
				continue;
			}
			fail[next[now][i]] = next[fail[now]][i];
			val[next[now][i]] |= val[next[fail[now]][i]];
			q.push(next[now][i]);
		}
	}
}

int main()
{
	int i, j, k;
	scanf("%d %d %d", &m, &n, &r);
	for(i = 1; i <= n; i++)
	{
		scanf("%s", s + 1);
		insert();
	}
	make_fail();
	for(i = 1; i <= m; i++) sum *= r; 
	f[0][0] = 1;
	for(i = 1; i <= m; i++)
		for(j = 0; j <= cnt; j++)
		{
			if(val[j] || !f[i - 1][j]) continue;
			for(k = 1; k <= r; k++)
				if(!val[next[j][k]])
					f[i][next[j][k]] += f[i - 1][j];
		}
	for(i = 0; i <= cnt; i++) ans += f[m][i];
	printf("%.5lf\n", double(sum - ans) / double(sum));
	return 0;
}

  

posted @ 2017-09-14 17:33  zht467  阅读(132)  评论(0)    收藏  举报