| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 52350 | Accepted: 18041 |
Description
Input
Output
Sample Input
5 Ab3bd
Sample Output
2
设原序列S的逆序列为S‘ ,则这道题目的关键在于,
最少需要补充的字母数 = 原序列S的长度 — S和S‘的最长公共子串长度
刚开始做的时候没有想到滚动数组,结果就mle了。。(后来听说改成short int ,结果就ac了)空间开销很大
#include <iostream>
#include <cstring>
using namespace std;
#define maxn 5005
char str[maxn];//输入的字符串
char nstr[maxn];//输入的字符串的逆序列
short int dp[maxn][maxn];//定义动态二维数组并初始化
int main()
{
int n;//输入的字符串长度
cin>>n;
dp[0][0]=0;
memset(dp,0,sizeof(dp));
int i,j;
for(i=1,j=n;i<=n&&j>=1;i++,j--)
{
cin>>str[i];
nstr[j]=str[i];//给逆序列赋值
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(str[i]==nstr[j])//如果字符相等,dp[i][j]等于左上值加1
dp[i][j]=dp[i-1][j-1]+1;
if(str[i]!=nstr[j])//不相等,dp[i][j]等于上方和左方dp值得最大值
dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];
}
cout<<n-dp[n][n]<<endl;
return 0;
}
滚动数组的作用在于优化空间,主要应用在递推或动态规划中(如01背包问题)。因为DP题目是一个自底向上的扩展过程,我们常常需要用到的是连续的解,前面的解往往可以舍去。所以用滚动数组优化是很有效的。利用滚动数组的话在N很大的情况下可以达到压缩存储的作用。
例:斐波那契数列:
一般代码
int fib(int n)
{
Fib[0] = 0;
Fib[1] = 1;
Fib[2] = 1;
for(int i = 3; i <= n; ++i)
Fib[i] = Fib[i - 1] + Fib[i - 2];
return Fib[n];
} int fib(int n)
{
Fib[1] = 0;
Fib[2] = 1;
for(int i = 2; i <= n; ++i)
{
Fib[0] = Fib[1];
Fib[1] = Fib[2];
Fib[2] = Fib[0] + Fib[1];
}
return Fib[2];
} #include <iostream>
#include <cstring>
using namespace std;
#define maxn 5005
char str[maxn];//输入的字符串
char nstr[maxn];//输入的字符串的逆序列
int dp[2][maxn];//定义动态二维数组并初始化
int main()
{
int n;//输入的字符串长度
cin>>n;
dp[0][0]=0;
memset(dp,0,sizeof(dp));
int i,j;
for(i=1,j=n;i<=n&&j>=1;i++,j--)
{
cin>>str[i];
nstr[j]=str[i];//给逆序列赋值
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(str[i]==nstr[j])//如果字符相等,dp[i][j]等于左上值加1
dp[i%2][j]=dp[(i-1)%2][j-1]+1;
if(str[i]!=nstr[j])//不相等,dp[i][j]等于上方和左方dp值得最大值
dp[i%2][j]=dp[(i-1)%2][j]>dp[i%2][j-1]?dp[(i-1)%2][j]:dp[i%2][j-1];
}
cout<<n-dp[n%2][n]<<endl;
return 0;
}
POJ 1159 Palindrome(lcs加滚动数组),布布扣,bubuko.com
原文:http://blog.csdn.net/sunshumin/article/details/38294191