洛谷 2187 小Z的笔记
【题解】
DP. 设f[i]表示前i个字母,保留第i个字母,最多可以保留多少个字母;设g[i]为当前字母为i的位置对应的f的最大值。
转移方程就是f[i]=max(f[i], g[j]+1) (j与s[i]不冲突) , g[s[i]]=max(g[s[i]], f[i]) .
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define rg register 6 #define N 200010 7 using namespace std; 8 int n,m,ans,f[N],g[26]; 9 char s[N],c; 10 bool v[26][26]; 11 inline int read(){ 12 int k=0,f=1; char c=getchar(); 13 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 14 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 15 return k*f; 16 } 17 int main(){ 18 n=read(); 19 scanf("%s",s+1); 20 m=read(); 21 while(m--){ 22 c=getchar(); while(c<'a'||c>'z') c=getchar(); int x=c-'a'; 23 c=getchar(); while(c<'a'||c>'z') c=getchar(); int y=c-'a'; 24 v[x][y]=v[y][x]=1; 25 } 26 for(rg int i=1;i<=n;i++){ 27 for(rg int j=0;j<26;j++)if(!v[s[i]-'a'][j]){ 28 f[i]=max(f[i],g[j]+1); 29 } 30 g[s[i]-'a']=max(g[s[i]-'a'],f[i]); 31 ans=max(ans,f[i]); 32 } 33 printf("%d\n",n-ans); 34 return 0; 35 }