3.31小模拟(lcs最长公共子序列

T2

树上小背包,记录一下,貌似和重心没太大关系吧?

#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<vector>
#include<string>
using namespace std;
const int N = 105;
int val[N];
vector<int>g[N];
int dp[N],dep[N],siz[N],n,f[N];
void dfs1(int u,int fa){
    dep[u] = dep[fa] + 1;
    for(int v : g[u]){
        if(v == fa)continue;
        dfs1(v,u);
        f[u] += f[v];
    }
}
int ans = 1e9;
void dfs2(int u,int fa){
    for(int v : g[u]){
        if(v == fa)continue;
        dp[v] = dp[u] + f[1] - f[v] * 2;// 右边的减少f[v] 左边的增加f[1]-f[v]
        ans = min(ans,dp[v]);
        dfs2(v,u);
    }    
}
int main(){
    #ifdef hahaha
    freopen("hospital.in","r",stdin);
    freopen("hospital.out","w",stdout);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        int l,r;
        scanf("%d%d%d",&val[i],&l,&r);
        f[i] = val[i];
        if(l)g[i].push_back(l),g[l].push_back(i);
        if(r)g[i].push_back(r),g[r].push_back(i);
    }
    dfs1(1,0);
    for(int i=1;i<=n;++i)dp[1] += (dep[i]-1) * val[i];
    ans = dp[1];
    dfs2(1,0);
    printf("%d",ans);
}

T3求最长公共子序列

dp[i][j] :一个串到 i 另一个到 j 最长子序列长度,转移看下面吧,在这里把板子留了,以防我忘掉(

#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<vector>
#include<string>
#define hahaha
using namespace std;
int dp[205][205];
int main(){
    #ifdef hahaha
    freopen("lcs.in","r",stdin);
    freopen("lcs.out","w",stdout);
    #endif
    char s1[205],s2[205];
    scanf("%s%s",s1+1,s2+1);
    int n = strlen(s1+1),m = strlen(s2+1);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) {
            dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
            dp[i][j] = max(dp[i][j],dp[i-1][j-1] + (s1[i] == s2[j]));    
        }
    printf("%d",dp[n][m]);
}

 

posted @ 2022-03-31 23:06  Xu_brezza  阅读(38)  评论(0编辑  收藏  举报