码迷,mamicode.com
首页 > 其他好文 > 详细

sgu-201 Non Absorbing DFA

时间:2015-01-21 22:39:59      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:sgu

 题目大意:

给你一个字符串,表示拥有的字符为长度L,即操作的种类L ,然后给你一个无向图,有n个顶点,标号从1~n,之后输入一个S,表示起点,即你一开始所在的位置,然后给你一个集合Σ,先输入元素个数,然后输入包含的元素有哪些。然后再给你一个数N,表示操作的字符串长度。最后停留的点必须在Σ中。

之后输入一个n*L的矩阵,第i行第j列表示在点号为i的点上进行字符操作 j 将会到达的点,记为change[ i ][ j ]。

之后又是一个n*L的矩阵,第i行第j列表示在点号为i的点上进行字符操作 j 是否会消耗掉当前的字符 j ,如果是0,表示会消耗,跳到下一个字符,如果是1,表示不会消耗字符,在下一个点继续进行操作j。记为cost[ i ][ j ]

然后就是要得出有多少种操作字符串。


 解题思路:

首先预处理。

首先对于点i的字符操作 j ,如果cost[ i ][ j ]=0,表示直接消耗掉,我们先不管。如果cost[ i ][ j ]=1,那么就需要查找到最后到消耗掉这个字符会到达哪里。但是有可能会出现最后无法消耗掉,那么我们就打一个标记,说明不能在 i 点进行 j 操作。

然后直接DP,f[ i ][ j ]表示消耗i个字母最后在点 j 停留的种类。

如果 j 可以  进行 p 操作,那么

f[ i+1 ][ change[ j ][ p ] ]+=f[i][j] (p=1->L)

最后输出所有 的f[ N ][ Σ[i] ]

要写高精度!!!!


AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define MAX(a,b) ((a)>(b)?(a):(b))

using namespace std;
int len;//字符数 
int U;//点数 
int S;//起点 
int xigema[1010]={0};
int sx=0;//Σ的包含数 
int n;//答案的长度 
struct bian_
{
	int change;
	int cost;
}bian[10010][30]={{{0,0}}};
int f[70][1010][50]={{{0}}};
int hash[1010]={0};
int Times=0;

void Add(int p,int q,int pp,int qq)
{
	f[p][q][0]=MAX(f[p][q][0],f[pp][qq][0]);
	for(int i=1;i<=f[p][q][0];i++)
	{
		f[p][q][i]+=f[pp][qq][i];
		f[p][q][i+1]+=f[p][q][i]/10000;
		f[p][q][i]%=10000;
	}
	for(int i=f[p][q][0];f[p][q][i+1]>0;i++,f[p][q][0]++)
	{
		f[p][q][i+1]+=f[p][q][i]/10000;
		f[p][q][i]%=10000;
	}
	return;
}

int dfs(int k,int p)
{
	if(hash[k]==Times)
		return -1;
	hash[k]=Times;
	if(bian[k][p].cost==0)
		return bian[k][p].change;
	else return dfs(bian[k][p].change,p);
}

int main()
{
	char ch[10010]="\0";
	gets(ch);
	len=strlen(ch);
	for(;ch[len-1]=='\n' || ch[len-1]=='\r';ch[--len]='\0');
	scanf("%d",&U);
	scanf("%d",&S);
	scanf("%d",&sx);
	for(int i=1;i<=sx;i++)
	{
		int j;
		scanf("%d",&j);
		xigema[j]=1;
	}
	for(int i=1;i<=U;i++)
		for(int j=1;j<=len;j++)
			scanf("%d",&bian[i][j].change);
	for(int i=1;i<=U;i++)
		for(int j=1;j<=len;j++)
			scanf("%d",&bian[i][j].cost);
	scanf("%d",&n);
	
	for(int i=1;i<=U;i++)
		for(int j=1;j<=len;j++)
			if(bian[i][j].cost==1)
			{
				Times++;
				bian[i][j].change=dfs(bian[i][j].change,j);
				if(bian[i][j].change!=-1)
					bian[i][j].cost=0;
			}
	f[0][S][0]=f[0][S][1]=1;
	
	for(int i=0;i<n;i++)
		for(int j=1;j<=U;j++)
			for(int p=1;p<=len;p++)
				if(bian[j][p].cost==0)
					Add(i+1,bian[j][p].change,i,j);
					
	
	for(int i=1;i<=U;i++)
		if(xigema[i]==1)
			Add(0,0,n,i);
	
	printf("%d",f[0][0][f[0][0][0]]);
	for(int i=f[0][0][0]-1;i>0;i--)
		printf("%04d",f[0][0][i]);
	return 0;
}


sgu-201 Non Absorbing DFA

标签:sgu

原文地址:http://blog.csdn.net/qq_21995319/article/details/42974339

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!