题意:给定一个字符序列,求最少添加多少个字符能让它变成对称序列
分析:这题的做法竟然是把序列颠倒之后求最长公共子序列,然后n-dp[n][n]就是答案。记住这种做法。
在这里再说一次最长公共子序列的做法:dp[i][j]表示序列1的前i个字符和序列2的前j个字符比较时的最长公共子序列的长度,状态转移公式:1.当a[i]==b[j]时,dp[i][j]=dp[i-1][j-1]+1;2.否则,dp[i][j]=max(dp[i-1][j],dp[i][j-1])
代码:
#include<iostream> using namespace std; int n; char a[5005],b[5005]; int dp[2][5005]; int max(int i,int j) { return i>j?i:j; } void DP() { for(int i=0;i<=n;i++) dp[i%2][0]=0; for(int i=0;i<=n;i++) dp[0][i]=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i-1]==b[j-1]) dp[i%2][j]=dp[(i-1)%2][j-1]+1; else dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]); } } } int main() { while(cin>>n){ cin>>a; for(int i=n-1;i>=0;i--) b[n-i-1]=a[i]; DP(); cout<<n-dp[n%2][n]<<endl; } }
!HDU 1513 Palindrome--dp--(最长公共子序列模型)
原文地址:http://blog.csdn.net/ac_0_summer/article/details/46583837