您的位置:首页 > 其它

区间DP UVA 10453 Make Palindrome

2015-08-17 15:27 369 查看
题目传送门

 /*
题意:问最少插入多少个字符使得字符串变成回文串
区间DP:dp[i][j]表示[l, r]的字符串要成为回文需要插入几个字符串,那么dp[l][r] = dp[l+1][r-1]; (str[l] == str[r])
dp[l][r] = min (dp[l+1][r], dp[l][r-1]) + 1,然后按照状态转移递归输出路径
*/
/************************************************
* Author        :Running_Time
* Created Time  :2015-8-17 14:42:57
* File Name     :UVA_10453.cpp
************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 1e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
char str[MAXN];
int dp[MAXN][MAXN];

void print(int l, int r)    {
if (l > r)  return ;
if (l == r) printf ("%c", str[l]);
else if (str[l] == str[r])   {
printf ("%c", str[l]);
print (l + 1, r - 1);
printf ("%c", str[l]);
}
else if (dp[l][r] == dp[l+1][r] + 1)    {
printf ("%c", str[l]);
print (l + 1, r);
printf ("%c", str[l]);
}
else    {
printf ("%c", str[r]);
print (l, r - 1);
printf ("%c", str[r]);
}
}

void work(void) {
memset (dp, 0, sizeof (dp));
int len = strlen (str);
for (int i=2; i<=len; ++i)  {
for (int j=0; j+i-1<len; ++j)   {
int k = j + i - 1;
int &res = dp[j][k] = INF;
if (str[j] == str[k])   res = dp[j+1][k-1];
res = min (res, min (dp[j+1][k], dp[j][k-1]) + 1);
}
}
printf ("%d ", dp[0][len-1]);
print (0, len - 1); puts ("");
}

int main(void)    {     //UVA 10453 Make Palindrome
while (scanf ("%s", str) == 1)  {
work ();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: