HDU 1159 【DP之最長公共子序列】
阿新 • • 發佈:2019-02-08
類似於字典序比較的最長公共子序列,
只要找到狀態方程就比較好搞,
從角標1開始計算不會出錯,從0還是報錯了;
切防止對比溢位要在本來的基礎上+1計算;
言歸正傳:
DP型別都是狀態方程很重要;
假設兩個作對比,分別是s1,s2,則一定有 則dp[i][j] 就為s1前 i 個和s2前 j 個的公共子序列;
動態方程就是
if(s1[i]==s2[j]) { dp[i][j]=dp[i-1][j-1]+1; } else { if(dp[i][j-1]>dp[i-1][j]) { dp[i][j]=dp[i][j-1]; } else dp[i][j]=dp[i-1][j]; }
AC程式碼就是:
#include <iostream> #include <string.h> #include <cstdio> using namespace std ; const int maxi = 1000; int ma[maxi][maxi]; char s1[maxi],s2[maxi]; int main() { while(scanf("%s%s",s1+1,s2+1)!=EOF) { int n1 = strlen(s1+1); int n2 = strlen(s2+1); for(int i = 0 ; i <=n1;i++) ma[i][0]=0; for(int j = 0 ; j<=n2;j++) ma[0][j]=0; for(int i = 1 ; i<=n1;i++) { for(int j = 1 ; j<=n2;j++) { if(s1[i]==s2[j]) { ma[i][j]=ma[i-1][j-1]+1; } else { if(ma[i][j-1]>ma[i-1][j]) { ma[i][j]=ma[i][j-1]; } else ma[i][j]=ma[i-1][j]; } } } cout<<ma[n1][n2]<<endl; } return 0 ; }
DP就是找狀態方程去證明,慢慢找,需要大量練習;