[LUOGU] P2187 小Z的笔记

看范围猜方程,应该是O(n)级别的

f[i]表示前i个合法的最小代价,转移需要枚举断点位置,O(n^2)

f[i]表示前i个合法留下的最大个数,同时更新距离最近的26个字母的位置,O(n)转移

f[i]=max{f[pos[j]+1} 0<=j<=25,j和a[i]可以同时出现

#include<iostream>
#include<cstdio>

using namespace std;

const int MAXN=1000005;

char a[MAXN],s[10];
bool fb[27][27];
int n,m;
int f[MAXN],pos[32];

int main(){
  scanf("%d%s",&n,a+1);
  for(int i=1;i<=n;i++) a[i]-='a';
  scanf("%d",&m);
  for(int i=1;i<=m;i++){
    scanf("%s",s);int x=s[0]-'a',y=s[1]-'a';
    fb[x][y]=1;fb[y][x]=1;
  }
  for(int i=1;i<=n;i++){
    f[i]=1;
    for(int j=0;j<26;j++){
      if(!fb[a[i]][j]) f[i]=max(f[i],f[pos[j]]+1);
    }
    pos[a[i]]=i;
  }
  cout<<n-f[n];
  return 0;
}

本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9262027.html

原文地址:https://www.cnblogs.com/ghostcai/p/9262027.html