【持續更新】碰見頻率高的幾種dp

都是一些面試筆試常見的問題,基本思路理解了就很簡單。

 

最長公共子序列

#include <bits/stdc++.h>
using namespace std;
/*
最長公共子序列
*/
const int maxn=2e3+10;
char s1[maxn];
char s2[maxn];
int dp[maxn][maxn];
​
int dfs(int x,int y){
    int &ans=dp[x][y];
    if(ans!=-1)return ans;
    if(x==0||y==0)return ans=0;
    ans=0;
    if(s1[x]==s2[y]){
        ans=dfs(x-1,y-1)+1;
    }
    else{
        ans=max(dfs(x-1,y),dfs(x,y-1));
    }
    return ans;
}
signed main(){
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    int len1=strlen(s1+1);
    int len2=strlen(s2+1);
    for(int i=0;i<=len1;i++){
        for(int j=0;j<=len2;j++){
            dp[i][j]=-1;
        }
    }
    printf("%d\n",dfs(len1,len2));
    return 0;
​
}

最長上升子序列

#include <bits/stdc++.h>
using namespace std;
​
const int maxn=1e5+10;
int n,L;
int c[200000];
int lowbit(int x){
    return x&-x;
}
void add(int x,int v){
    while(x<=L){
        c[x]=max(c[x],v);
        x+=lowbit(x);
    }
}
int query(int x){
    int ans=0;
    while(x){
        ans=max(c[x],ans);
        x-=lowbit(x);
    }
    return ans;
}
vector<int>v;
int a[200000];
int getid(int cur){
    return lower_bound(v.begin(),v.end(),cur)-v.begin()+1;
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        v.push_back(a[i]);
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    L=v.size();
    int ans=0;
    for(int i=1;i<=n;i++){
        int now=getid(a[i]);
        int cur=query(a[i]-1)+1;
        ans=max(ans,cur);
        add(now,cur);
    }
    printf("%d\n",ans);
    return 0;
​
}

編輯距離

#include <bits/stdc++.h>
using namespace std;
​
const int maxn=2e3+10;
int dp[maxn][maxn];
char s[maxn],t[maxn];
const int INF=1e9;
int dfs(int x,int y){
    int &ans=dp[x][y];
    if(ans!=-1)return ans;
    if(x==0||y==0){
        return ans=x==0?y:x;
    }
    ans=INF;
    int flag=s[x]==t[y]?0:1;
    ans=min(dfs(x-1,y)+1,min(dfs(x,y-1)+1,dfs(x-1,y-1)+flag));
    return ans;
}
signed main(){
    scanf("%s",s+1);
    scanf("%s",t+1);
    int len1=strlen(s+1),len2=strlen(t+1);
    for(int i=0;i<=len1;i++){
        for(int j=0;j<=len2;j++){
            dp[i][j]=-1;
        }
    }
    printf("%d\n",dfs(len1,len2));
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章