AcWing 1222. 密码脱落

原题链接

考察:区间DP+线性dp

思路一:

       正向求解,f[i][j]表示[i,j]区间内应该删去的字符数.要注意的是如果i>j,那么为不合法区间,设置f[i][j] = 0.i = j,单个字符一定回文,f[i][j] = 0.接下来就是划分集合:s[i]=s[j]可缩小到f[i+1,j-1].如果s[i]!=j,在f[i,j-1]与f[i+1,j]取最小值.(对应去掉左端点或去掉右端点的情况,都去的情况可被覆盖)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1010;
 7 char s[N];
 8 int f[N][N];
 9 int main()
10 {
11     scanf("%s",s+1);
12     int len = strlen(s+1);
13     memset(f,0x3f,sizeof f);
14     for(int i=0;i<=len+5;i++)
15       for(int j=0;j<=i;j++) f[i][j] = 0;
16     for(int i=len;i>=1;i--)
17         for(int j=i;j<=len;j++)
18         {
19             if(s[i]==s[j]) f[i][j] = f[i+1][j-1];
20             else f[i][j] = min(f[i+1][j],f[i][j-1])+1;
21         }
22     printf("%d\n",f[1][len]);
23     return 0;
24 }
思路一

思路二:

        逆向求解,f[i][j]表示[i,j]区间内最大的对称序列长度.答案为串长度-回文序列长度.

        划分集合:如果l,r都在里面,f[i][j] = f[i+1][j-1]+2;l不在回文串内,r在,此情况存在条件是[l+1,r]内存在与r相等的字符.此情况太难求,可以考虑覆盖即f[l+1,r].同理l在r不在,都不在就是f[l+1,r-1].

注意:f[l]会用到f[l+1]所以需要l倒着推,也可以直接枚举区间长度.

posted @ 2021-02-10 15:49  acmloser  阅读(54)  评论(0编辑  收藏  举报