Codeforces 919D

919D - Substring

思路:

拓扑排序判环+DAG上dp+记忆化搜索

状态:dp[i][j]表示以i为起点的路径中j的最大出现次数

初始状态:dp[i][j]=1(i have no son && w[i]==j)

                  dp[i][j]=0(i have no son && w[i]!=j)

状态转移:dp[i][j]=max(dp[t][j])(t is i's son)

     dp[i][j]++(w[i]==j)

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=3e5+5;
int head[N];
int w[N];
int in[N];
int tin[N];
int dp[N][26];
int cnt=0;
struct edge{
    int to,next;
}edge[N];
void add_edge(int u,int v){
    edge[cnt].to=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
bool topo_sort(int n){
    queue<int>q;
    int cnt=0;
    for(int i=1;i<=n;i++)if(tin[i]==0)q.push(i),cnt++;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=head[u];~i;i=edge[i].next){
            tin[edge[i].to]--;
            if(tin[edge[i].to]==0)q.push(edge[i].to),cnt++;
        }
    }
    return cnt>=n;
}
int dfs(int u,int x){
    if(dp[u][x]!=-1)return dp[u][x];
    dp[u][x]=0;
    for(int i=head[u];~i;i=edge[i].next){
        dp[u][x]=max(dp[u][x],dfs(edge[i].to,x));
    }
    if(w[u]==x)dp[u][x]++;
    return dp[u][x];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    mem(head,-1);
    mem(dp,-1);
    int n,m,u,v;
    string s;
    cin>>n>>m;
    cin>>s;
    for(int i=0;i<s.size();i++)w[i+1]=s[i]-'a';
    for(int i=0;i<m;i++)cin>>u>>v,add_edge(u,v),in[v]++,tin[v]++;
    if(topo_sort(n)){
        int ans=0;
        for(int i=1;i<=n;i++){
            if(in[i]==0){
                for(int j=0;j<26;j++){
                    ans=max(ans,dfs(i,j));
                }
            }
        }
        cout<<ans<<endl;
    }
    else cout<<-1<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/8399193.html