Poj1159
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 58763 | Accepted: 20419 |
Description
Input
Output
Sample Input
5 Ab3bd
Sample Output
2
题意: 输出至少需要往序列中加入多少个字母才能使序列变长回文串
实际上就是n-正序逆序的最长子序列
开始想着直接输入的时候是前一半和后一半字符串的最长子序列,但是输入总有问题…就改成尝试网上的正逆串比较了~
dp[maxn][maxn]
当maxn太大时,会超出内存限制,需要改装成滚动数组【常在dp中使用】因为后面的结果就仅仅依赖于前面最近的一次结果。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #define maxn 5005 using namespace std; char S[maxn],T[maxn]; int dp[2][maxn]; int main(){ int n; // freopen("1159.txt","r",stdin); scanf("%d",&n); scanf("%s",S); for(int i=0;i<n;i++){ T[n-1-i]=S[i]; } int e=0; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ e=1-e; for(int j=0;j<n;j++){ if(S[i]==T[j]){ dp[e][j+1]=dp[1-e][j]+1; } else{ dp[e][j+1]=max(dp[e][j],dp[1-e][j+1]); } } } cout<<n-dp[e][n]<<endl; return 0; }
超水的本人,读取一半字符串的代码在下面…发现问题的麻烦联系我TT…始终不能正确写入T……
scanf("%d",&n); int i; getchar(); for( i=0;i<n/2;i++){ scanf("%c",&S[i]); } if(n%2==0){ scanf("%c",&S[++i]); } else{getchar();} //cout<<"i="<<i<<endl; int j; for( j=0;i+j<n-1;j++){ scanf("%d",&T[j]); }