1159
2011-04-12 18:38
120 查看
/* DP 此题的方程是 DP[i][j],i是左下标,j是右下标 DP[i][j] 表示从i到j的字符串需要加多少个字符才能使其成为回文串 if( in[i]==in[j] ) DP[i][j] = DP[i+1][j-1]; else DP[i][j] = MIN(DP[i+1][j],DP[i][j-1])+1; 但是此题的内存要求很小,DP 行不通。从方程中可以看出,i只和i+1有关,所以可以使用滚动数组 起初我使用的mod = 3的滚动。按照长度来进行DP的,这样两层的滚动不够,因为除了当前和减一,还有减二的情况 所以,需要三层 还有一种构造滚动数组的方法是:不使用长度来进行DP,而是使用下标。 对于这样做的好处是可以少一层数组 if in[i]== in[j] DP[i%2][j] = DP[(i+1)%2][j-1]; (i+1)%2是上次从i-1处开始的DP结果 else DP[i%2][j] = MIN(DP[(i+1)%2][j],DP[i%2][j-1])+1; */ // include file #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <ctime> #include <iostream> #include <sstream> #include <fstream> #include <iomanip> #include <bitset> #include <algorithm> #include <string> #include <vector> #include <queue> #include <set> #include <list> #include <functional> using namespace std; // typedef typedef long long LL; typedef unsigned long long ULL; // #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) #define FORi(a,b,c) for(int i=(a);i<(b);i+=c) #define FORj(a,b,c) for(int j=(a);j<(b);j+=c) #define FORk(a,b,c) for(int k=(a);k<(b);k+=c) #define FORp(a,b,c) for(int p=(a);p<(b);p+=c) #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c) #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c) #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c) #define FF(i,a) for(int i=0;i<(a);i++) #define FFD(i,a) for(int i=(a)-1;i>=0;i--) #define Z(a) (a<<1) #define Y(a) (a>>1) const double eps = 1e-6; const double INFf = 1e100; const int INFi = 1000000000; const LL INFll = (LL)1<<62; const double Pi = acos(-1.0); template<class T> inline T sqr(T a){return a*a;} template<class T> inline T TMAX(T x,T y) { if(x>y) return x; return y; } template<class T> inline T TMIN(T x,T y) { if(x<y) return x; return y; } template<class T> inline void SWAP(T &x,T &y) { T t = x; x = y; y = t; } template<class T> inline T MMAX(T x,T y,T z) { return TMAX(TMAX(x,y),z); } template<class T> inline T MMIN(T x,T y,T z) { return TMIN(TMIN(x,y),z); } // code begin /* int N; char in[5010]; int DP[2][5010]; int main() { read; write; while(scanf("%d",&N)==1) { scanf("%s",in); memset(DP,0,sizeof(DP)); for(int i=N-2;i>=0;i--) { for(int j=i+1;j<N;j++) { if(in[i]==in[j]) { DP[i&1][j] = DP[(i+1)&1][j-1]; } else { DP[i&1][j] = TMIN(DP[i&1][j-1],DP[(i+1)&1][j])+1; } } } printf("%d\n",DP[0][N-1]); } return 0; } */ int N; char in[5010]; int DP[3][5010]; int main() { read; write; while(scanf("%d",&N)==1) { scanf("%s",in); memset(DP,-1,sizeof(DP)); FORi(0,N,1) { DP[0][i] = 0; DP[1][i] = 0; } // 初试时DP状态1 FORi(2,N+1,1) { FORj(0,N,1) { if(j+i-1>=N) break; if(in[j]==in[j+i-1]) { DP[i%3][j] = DP[(i-2+3)%3][j+1]; } else { DP[i%3][j] = TMIN(DP[(i-1+3)%3][j]+1,DP[(i-1+3)%3][j+1]+1); } } } printf("%d\n",DP[N%3][0]); } return 0; }
相关文章推荐
- 动态规划练习二:HDU ACM 1159 Common Subsequence
- POJ 1159 Palindrome
- HDU 1159 最长公共子序列问题 动态规划
- POJ1159:Palindrome(回文数)
- poj 1159 回文词
- POJ1159
- HDU 1159 最长公共子序列
- HDU 1159 最长公共子序列
- hdu1159
- 神DP POJ 1159 Palindrome
- poj 1159
- HDU1159--Common Subsequence
- poj1159 —— 一个字符串,求最少插入几个字符可以组成回文
- Longest common subsequence problem and poj 1159 Palindrome
- poj 1159 Palindrome(最长公共子串)
- HDOJ 1159 Common Subsequence 杭电 ACM
- HDU1513 && POJ1159:Palindrome(LCS)
- poj1159 LCS
- poj 1159 Palindrome
- POJ 1159 Palindrome