密码脱落-蓝桥杯-最大公共子序列
https://www.acwing.com/problem/content/description/1224/
最长公共子序列问题在《算法导论》P222页有其原理证明。
“比对两段DNA序列的相似度”就是一个很好的例子。
动态规划的核心思想就是自底向上地解决递归中的重复子结构问题。利用空间迭代(或者说是状态转移)来换取递归的堆栈操作和时间。
纯dfs解法1:33分,但其实应该是错的,最小解应该取两个dfs的min
#include
using namespace std;
string s;
int ans;
void dfs(int i,int j,int u){
if(i>=j) {
ans=u;
return ;
}
if(s[i]!=s[j]){
dfs(i+1,j,u+1);
dfs(i,j-1,u+1);
}else{
dfs(i+1,j-1,u);
}
return ;
}
int main(){
cin>>s;
int n=s.size();
dfs(0,n-1,0);
cout<
纯dfs解法2:正确写法:
此题无法继续剪枝;
#include
using namespace std;
string s;
int ans;
int dfs(int i,int j,int u){
if(i>=j) {
return u;
}
if(s[i]!=s[j]){
return min(dfs(i+1,j,u+1),dfs(i,j-1,u+1));
}else{
return dfs(i+1,j-1,u);
}
}
int main(){
cin>>s;
int n=s.size();
cout<
3.dp区间规划:
为了方便理解我还是单独开辟空间给逆序串来比对
优雅而快捷~
#include
using namespace std;
const int N=1010;
string s;
int dp[N][N];
int main(){
cin>>s;
int n=s.size();
string s2=s;
reverse(s2.begin(),s2.end()); //单独开辟空间给逆序串来比对
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(s[i]==s2[j]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
cout<