ACM: 回文串 dp题 poj 1159 (滚动…
2016-05-19 23:18
483 查看
Palindrome
Description
A palindrome is a symmetrical string, that is,
a string read identically from left to right as well as from right
to left. You are to write a program which, given a string,
determines the minimal number of characters to be inserted into the
string in order to obtain a palindrome.
As an example, by inserting 2 characters, the
string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or
"Adb3bdA"). However, inserting fewer than 2 characters does not
produce a palindrome.
Input
Your program is to read from standard input.
The first line contains one integer: the length of the input string
N, 3 <= N <= 5000. The second line
contains one string with length N. The string is formed from
uppercase letters from 'A' to 'Z', lowercase letters from 'a' to
'z' and digits from '0' to '9'. Uppercase and lowercase letters are
to be considered distinct.
Output
Your program is to write to standard output.
The first line contains one integer, which is the desired minimal
number.
Sample Input
5
Ab3bd
Sample Output
2
题意: 给你一个字符串,计算最少插入多少个字母形成回文串.
解题思路:
1. dp题肯定先找出状态转移方程. 一开始想把串分成两部分找最长相同字串.
2. 但是发现并不是同时两个字串都要添加字母,每次只是添加一个就行.
3. 状态转移方程: 设dp[i][j]是第i到第j字符需要至少添加多少个字符形成回文串.
即: if(str[i] == str[j]) dp[i][j] =
dp[i+1][j-1]; (i = n-1
>> i = 1;) (j = i+1
>> j = n)
else dp[i][j] = min(dp[i+1][j] , dp[i][j-1]) + 1;
4. 郁闷的是发现5000的二位数组开不下.T.T.网上看见讨论用.short型.还好暴力AC.
5. 还发现大牛们的是滚动数组. 每次只需e = 1-e;变换即可. 学习学习.
代码1:
#include
<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 5005
int n;
char str[MAX];
short dp[MAX][MAX];
inline int min(int a,int b)
{
return a
> b ? a : b;
}
int main()
{
//
freopen("input.txt","r",stdin);
while(scanf("%d",&n) !=
EOF)
{
getchar();
int i, j;
for(i = n; i >= 1; --i)
scanf("%c",&str[i]);
str[i] = '\0';
memset(dp,0,sizeof(dp));
for(int i = n-1; i >= 1;
--i)
{
for(int j = i+1; j <= n;
++j)
{
if(str[i] == str[j])
dp[i][j] = dp[i+1][j-1];
else
dp[i][j] = min(dp[i+1][j],dp[i][j-1])+1;
}
}
printf("%d\n",dp[1]
);
}
return
0;
}
代码2:
#include
<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 5005
int n;
char str1[MAX], str2[MAX];
int dp[2][MAX];
inline int max(int a,int b)
{
return a
> b ? a : b;
}
int main()
{
//
freopen("input.txt","r",stdin);
while(scanf("%d",&n) !=
EOF)
{
getchar();
for(int i = 1; i <= n; ++i)
scanf("%c",&str1[i]);
str1[n+1] = '\0';
for(int i = 1; i <= n; ++i)
str2[i] =
str1[n-i+1];
str2[n+1] = '\0';
memset(dp,0,sizeof(dp));
int e = 0;
for(int i = 1; i <= n; ++i)
{
e =
1^e;
for(int j =
1; j <= n; ++j)
{
if(str1[i]
== str2[j])
dp[e][j] =
dp[1^e][j-1] + 1;
else
dp[e][j] =
max(dp[e][j-1],dp[1^e][j]);
}
}
printf("%d\n",n-dp[1^e]
);
}
return
0;
}
相关文章推荐
- ACM: polay定理 数论题 poj 1286 …
- ACM: polya定理 数论题 poj 2409
- ACM: 高精度运算 poj 1001 首次jav…
- ACM: polya模拟 数论题 poj 1026
- ACM: 深搜题 poj 3411
- ACM: 条件最短路 poj 1724 (没剪枝…
- ACM: 有难度的深搜题 poj 3373
- ACM: 模拟题 poj 2993
- Android中的异步任务
- ACM: hash题 poj 3274 (题目看了好…
- ACM: dp题(动态规划) poj 2151 (d…
- ACM: dp题 poj 1276 go on 动态规…
- ACM: 简单数塔题 dp题 poj 3176
- ACM: dp动态规划题(难) poj 3267 …
- ACM: 最优解 dp题 poj 1260
- ACM: 最长升序和最长降序 dp题 poj…
- QuickContactBadge的学习 快速关联联系人
- NFS服务器的构建与使用
- -bash: /tyrone/jdk/jdk1.8.0_91/bin/java: cannot execute binary file
- Mysqlite的基本用法