当前位置:编程学习 > C/C++ >>

SRM 557小记

250pt: 水题
500pt:状态压缩枚举,系统测试挂了,囧。。。
1000pt:可以这样抽象题意,构造长度为len的且包含模式串的总权值为0的串,求这样的串的个数,字符串由‘U’和‘D’组成,‘U’:+1     ‘D’:-1.
DP,套了个AC自动机,大材小用了- -
状态很简单的,转移的时候要注意转移到的状态是否已经包含模式串
[cpp] 
#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; 
    } 
}; 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,