其他分享
首页 > 其他分享> > [IOI2000] 回文字串 / [蓝桥杯 2016 省] 密码脱落(dp)

[IOI2000] 回文字串 / [蓝桥杯 2016 省] 密码脱落(dp)

作者:互联网

简单分析, 本题属于$2D/0D$问题,所以空间复杂度为$n^2$, 时间复杂度也是$n^2$

这里我们定义$dp$方程$dp[i][j]$为i到j的子字符串变为回文字符串需要插入的字符的个数

初始化$dp[i][j]$为$inf$, $dp[i][i] = 0$ 显然$dp[i]j[j]$可以从$dp[i + 1][j - 1]$转移过来, 也可以从$dp[i + 1][j]$或者$dp[i][j - 1]$转移过来, 我们只取三者最小值即可.

$ dp[i][j] = \begin{cases} min\{dp[i + 1][j - 1]\}& \text{if s[i] = s[j]}\\ min\{dp[i + 1][j] + 1, dp[i][j - 1] + 1\}& \text{if s[i]$\ne$s[j]}\\ 0 & \text{if i=j or (s[i]=s[j] and i+1=j)}\\ \end{cases}\\ $

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <queue>
 4 #include <vector>
 5 #include <cstring>
 6 #include <algorithm>
 7 using namespace std;
 8 constexpr int MAXN = 1e3 + 7;
 9 
10 using ll = long long;
11 
12 int dp[MAXN][MAXN];
13 
14 int main()
15 {
16     ios::sync_with_stdio(false);
17     cin.tie(nullptr);
18     cout.tie(nullptr);
19     memset(dp, 0x3f, sizeof dp);
20     string s;
21     cin >> s;
22     int n = s.length();
23     s = " " + s;
24     for (int i = 1; i <= n; ++i)
25     {
26         dp[i][i] = 0;
27     }
28     for (int len = 1; len <= n - 1; ++len)
29     {
30         for (int i = 1; i <= n - len; ++i)
31         {
32             int j = i + len;
33             if (s[i] == s[j])
34             {
35                 dp[i][j] = min(dp[i][j], len == 1 ? dp[i][i] : dp[i + 1][j - 1]);
36             }
37             else
38             {
39                 dp[i][j] = min(dp[i][j - 1] + 1, dp[i + 1][j] + 1);
40             }
41         }
42     }
43     cout << dp[1][n] << '\n';
44 
45     return 0;
46 }
View Code

 

标签:IOI2000,text,蓝桥,int,MAXN,文字串,using,include,dp
来源: https://www.cnblogs.com/daremo/p/15987842.html