codeforces#1150D. Three Religions(dp+序列自动机)

题目链接:

https://codeforces.com/contest/1150/problem/D

题意:

数据范围:

$1 \leq n \leq 100\,000$
$1 \leq q \leq 1000$

分析: 

ac代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=250+10;
int len[maxm][4],top[4];
int word[maxn],nex[maxn][30];
int dp[maxm][maxm][maxm];
int main()
{
    int n,q;
    scanf("%d %d",&n,&q);
    getchar();
    for(int i=1;i<=n;i++)
    {
        char key;
        scanf("%c",&key);
        word[i]=key-'a';
    }
    for(int i=0;i<30;i++)
        nex[n+1][i]=nex[n+2][i]=n+1;
    for(int i=n;i>=1;i--)
    {
        for(int j=0;j<30;j++)
            nex[i][j]=nex[i+1][j];
        nex[i][word[i]]=i;
    }
    for(int i=0;i<30;i++)nex[0][i]=nex[1][i];
    while(q--)
    {
        getchar();
        char comd;
        scanf("%c",&comd);
        if(comd=='+')
        {
            char key;
            int t,x;
            scanf("%d %c",&t,&key);
            x=key-'a';
            len[++top[t]][t]=x;
            for(int i=(t==1?top[1]:0);i<=top[1];i++)
                for(int j=(t==2?top[2]:0);j<=top[2];j++)
                    for(int k=(t==3?top[3]:0);k<=top[3];k++)
                        dp[i][j][k]=n+1;
            dp[0][0][0]=0;
            for(int i=(t==1?top[1]:0);i<=top[1];i++)
                for(int j=(t==2?top[2]:0);j<=top[2];j++)
                    for(int k=(t==3?top[3]:0);k<=top[3];k++)
                    {
//                        cout<<i<<" "<<j<<" "<<k<<endl;
//                         cout<<dp[i][j][k]<<endl;
                        if(i!=0)
                            dp[i][j][k]=min(dp[i][j][k],nex[dp[i-1][j][k]+1][len[i][1]]);
                        if(j!=0)
                            dp[i][j][k]=min(dp[i][j][k],nex[dp[i][j-1][k]+1][len[j][2]]);
                        if(k!=0)
                            dp[i][j][k]=min(dp[i][j][k],nex[dp[i][j][k-1]+1][len[k][3]]);
                    }
        }
        else
        {
            int t;
            scanf("%d",&t);
            top[t]--;
        }
       // cout<<dp[top[1]][top[2]][top[3]]<<endl;
        if(dp[top[1]][top[2]][top[3]]<=n)printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/carcar/p/10800879.html