看范围猜方程,应该是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;
}

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-11-27
  • 2021-12-23
  • 2021-12-19
  • 2021-12-03
  • 2021-12-13
  • 2022-01-12
猜你喜欢
  • 2021-10-06
  • 2021-07-14
  • 2021-07-29
  • 2021-10-12
  • 2021-09-20
  • 2021-08-18
相关资源
相似解决方案