SRM 557 小记

65 篇文章 0 订阅
21 篇文章 0 订阅

250pt: 水题

500pt:状态压缩枚举,系统测试挂了,囧。。。

1000pt:可以这样抽象题意,构造长度为len的且包含模式串的总权值为0的串,求这样的串的个数,字符串由‘U’和‘D’组成,‘U’:+1     ‘D’:-1.

DP,套了个AC自动机,大材小用了- -

状态很简单的,转移的时候要注意转移到的状态是否已经包含模式串

#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
using  namespace std;
const int mod = 1000000009;
const int M = 100;
const int CD = 26;
int sz;
int Q[M];
int ch[M][CD];
int ID[128];
int fail[M];
int val[M];
void Init(){
	fail[0]=0;  val[0]=0;
	sz=1;
	memset(ch[0],0,sizeof(ch[0]));
	for(int i=0;i<26;i++) ID[i+'A']=i;
}
void Insert(const char *s){
	int p=0;
	for(;*s;s++){
		int c=ID[*s];
		if(!ch[p][c]){
			memset(ch[sz],0,sizeof(ch[sz]));
			fail[sz]=val[sz]=0;
			ch[p][c]=sz++;
		}
		p=ch[p][c];
	}
	val[p]=1;
}
void Construct(){
	int *s=Q,*e=Q,v;
	for(int i=0;i<CD;i++) {
		if(ch[0][i]) {
			fail[ch[0][i]]=0;
			*e++ = ch[0][i];
		}
	}
	while(s!=e){
		int u=*s++;
		for(int i=0;i<CD;i++){
			if(v=ch[u][i]) {
				*e++=v;
				fail[v]=ch[fail[u]][i];
				val[v]|=val[fail[v]];
			}  else {
				ch[u][i]=ch[fail[u]][i];
			}
		}
	}
}
class FoxAndMountain{
public:
	int dp[55][55][55][2];//长度 节点  和  是否包含模式串
	int count(int n, string S) {
		Init();
		Insert(S.c_str());
		Construct();
		//for(int i=0;i<sz;i++) printf("fail[%d]=%d ",i,fail[i]);puts("");
		int H = 26;
		dp[0][0][0][0]=1;
		for(int i=0;i<=n;i++)
		{
			for(int j=0;j<sz;j++)
			{
				for(int h=0;h<H;h++)
				{
					for(int flag=0;flag<2;flag++)
					{
						if(!dp[i][j][h][flag]) continue;
						int x=ch[j][ID['U']],fx=val[x]|flag;
						int y=ch[j][ID['D']],fy=val[y]|flag;
						dp[i+1][x][h+1][fx]=(dp[i+1][x][h+1][fx]+dp[i][j][h][flag])%mod;
						if(h) dp[i+1][y][h-1][fy]=(dp[i+1][y][h-1][fy]+dp[i][j][h][flag])%mod;
					}
				}
			}
		}
		int ans=0;
		for(int i=0;i<sz;i++)
		{
			ans+=dp[n][i][0][1];ans%=mod;
		}
		return ans;
	}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值