这题用short水过,一看网上大牛的代码,居然说可以用滚动数组!太厉害了。
//poj_1159
#include <stdio.h>
#include <string.h>
#define N 5010
#define INF 10000
#define hpmin(a,b) (a)<(b)?(a):(b)
int n;
char str[N];
short int dp[N][N];
int main()
{
int i, len, j;
while ( scanf("%d", &n ) != EOF ) {
scanf("%s", str );
for ( i = 0; i < n; ++ i ) {
dp[i][i] = 0;
dp[i+1][i] = 0;
}
for ( len = 1; len < n; ++ len ) { //我总喜欢先枚举长度,再枚举起点i,计算终点j。如果是这样子,能难使用滚动数组
for ( i = 0; i < n-len; ++ i ) {
j = i+len;
dp[i][j] = INF;
if ( str[i] == str[j] ) {
dp[i][j] = dp[i+1][j-1];
}
dp[i][j] = hpmin( dp[i][j], dp[i+1][j]+1 );
dp[i][j] = hpmin( dp[i][j], dp[i][j-1]+1 );
}
}
printf("%d\n", dp[0][n-1] );
}
return 0;
}
滚动数组版本:
//poj_1159
#include <stdio.h>
#include <string.h>
#define N 5010
#define INF 10000
int hpmin( int x, int y ) {
return ( x < y ? x : y );
}
int n;
char str[N];
short int dp[2][N];
int main()
{
int i, j, a, b;
while ( scanf("%d", &n ) != EOF ) {
scanf("%s", str );
memset( dp, 0, sizeof(dp) );
a = 0;
for ( i = n-2; i >= 0; -- i ) { //直接先枚举i,再枚举j就很容易看出使用滚动数组。dp(i,j) = max( dp(i+1,j),dp(i,j-1), dp(i+1,j-1) )这种形式的dp应该都可以使用滚动数组优化
b = 1-a ;
dp[b][i] = 0;
for ( j = i+1; j < n; ++ j ) {
dp[b][j] = INF;
if ( str[i] == str[j] )
dp[b][j] = dp[a][j-1];
//dp[b][j] = hpmin( dp[b][j], dp[a][j]+1 );
//dp[b][j] = hpmin( dp[b][j], dp[b][j-1]+1 );
else {
//int tmp = hpmin( dp[a][j], dp[b][j-1] );
dp[b][j] = hpmin( dp[a][j], dp[b][j-1] ) + 1;
}
}
a = b;
//for ( j = 0; j < n; ++ j )
// printf("%d ", dp[b][j] );
//printf("\n");
}
printf("%d\n", dp[a][n-1] );
}
return 0;
}