首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

SRM 557 初记

2012-10-23 
SRM 557 小记250pt: 水题500pt:状态压缩枚举,系统测试挂了,囧。。。1000pt:可以这样抽象题意,构造长度为len的

SRM 557 小记

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


热点排行