UVA 1401Remember the WordDp

7948 단어 word
이 문제는 기억화 검색으로 시작하기 시작했다. 나는 역시 바보였다. 문자열 30w의 길이는 창고가 터진 것이 확실했다.
dp가 이동하는 방정식:str[i->j]에 dp[i]+=dp[j+1]가 나타나면
그리고 사전 트리로str[i->j]가 나타났는지 조회합니다.
#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <climits>

#include <string>

#include <iostream>

#include <map>

#include <cstdlib>

#include <list>

#include <set>

#include <queue>

#include <stack>

using namespace std;



char str[333333];

struct Node

{

    int gaoguo ; struct Node* next[30];

}node[2111111];

const int mod= 20071027;

int len;

Node* newnode()

{

    memset(&node[len],0,sizeof(node[len]));

    return &node[len++];

}

Node *rt;

void Insert(string s,Node*root)

{

    int len2=s.size();

    for(int i= 0;i< len2;i++){

        int cc=s[i]-'a';

        if(!root->next[cc]){

            root->next[cc]=newnode();

        }

        root=root->next[cc];

    }

    root->gaoguo=1;

}



int ask(string s,Node *root)

{

    int len2=s.size();

    for(int i=0;i<len2;i++){

        int cc=s[i]-'a';

        if(root->next[cc])

            root=root->next[cc];

        else return -1;

    }

    return root->gaoguo;

}

int len1;

int dp[333333];

char str1[333333];

int main()

{

    int n;

    int Icase= 0;

    while(scanf("%s",str)!=EOF){

        memset(dp,0,sizeof(dp));

        len1=strlen(str);

        scanf("%d",&n);

        len=0; rt = newnode();

        for(int i=0;i<n;i++){

            scanf("%s",str1); Insert(str1,rt);

        }

        printf("Case %d: ",++Icase);

        dp[len1]=1;

        for(int i=len1-1;i>=0;i--){

            string s="";

            for(int j=i;j<len1;j++){

                s+=str[j];

              //  cout<<s<<" "<<ask(s,rt)<<endl;

                int cc=ask(s,rt);if(cc==-1) break;

                if(cc==1) dp[i]+=dp[j+1],dp[i]%=mod;

            }

        }

        cout<<dp[0]%mod<<endl;

    }

    return 0;

}

좋은 웹페이지 즐겨찾기