Advertisement

上海计算机学会2024年7月月赛C++乙组T4修改回文(二)

阅读量:

修改回文(二)

内存限制: 256 Mb时间限制: 1000 ms

题目描述

给定一个仅由小写字母组成的字符串 s ,你可以添加一些字符(也可以不加),使其构成回文串。

请你输出在添加字符数最少的前提下,能够构成字典序最小的回文串。

输入格式

输入共一行,一个字符串 s

输出格式

输出共一行,题目所求的回文串。

数据范围

设 ∣s∣ 为字符串 s 的长度,则有:

  • 对于 30% 的数据,1≤∣s∣≤10
  • 对于 60% 的数据,1≤∣s∣≤100
  • 对于 100% 的数据,1≤∣s∣≤10^3
样例数据

输入:
ai
输出:
aia
说明:
字符串ai至少添加一个字符构成回文,该前提下,可以构造成aia、iai,但aia的字典序更小
输入:
iai
输出:
iai
说明:
不用添加任何字符
输入:
abca
输出:
abcba

解析:使用动态规划的方法,详见代码:

复制代码
 #include<bits/stdc++.h>

    
 using namespace std;
    
 //dp[i][j]为从i开头到j结尾添加字符后的最小回文串
    
 //为节省空间,将i为奇数存入dp[1][j],偶数存入dp[0][j];
    
 string dp[2][3005];
    
 string s;
    
 int len;//字符串长度
    
 int main() {
    
     cin >> s;
    
     len = s.length();
    
     for(int i = len - 1; i >= 0; i--) {//枚举所有开头为i,结尾为j的子串
    
     for(int j = i; j < len; j++) {
    
         if (i == j) {//单个字符,自己即为回文串
    
             dp[i % 2][j] = s[i];
    
         } else if (s[i] == s[j]) {//头尾相同,都加头或尾
    
             dp[i % 2][j] = s[i] + dp[(i + 1) % 2][j - 1] + s[j];
    
         } else {//头尾不同
    
             //都加头
    
             string t1 = s[i] + dp[(i + 1) % 2][j] + s[i];
    
             //都加尾
    
             string t2 = s[j] + dp[i % 2][j - 1] + s[j];
    
             //取最小值
    
             if (t1.length() > t2.length()) {
    
                 dp[i % 2][j] = t2;
    
             } else if (t1.length() < t2.length()) {
    
                 dp[i % 2][j] = t1;
    
             } else {
    
                 dp[i % 2][j] = min(t1, t2);
    
             }
    
         }
    
     }
    
     }
    
     cout << dp[0][len - 1];
    
     return 0;
    
 }
    
    
    
    

全部评论 (0)

还没有任何评论哟~