zoukankan      html  css  js  c++  java
  • 树形DP

    树形DP

    Tree painting

    #include <bits/stdc++.h>
    #include<stdint.h>
    #define int long long
    #define scan(n) scanf("%lld", &(n))
    #define scann(n, m) scanf("%lld%lld", &(n), &(m))
    #define scannn(a, b, c) scanf("%lld%lld%lld", &(a), &(b), &(c))
    #define prin(n) printf("%lld", (n))
    #define pb push_back
    #define mp make_pair
    #define ms(a) memset(a, 0, sizeof(a))
    #define fo(i, a, b) for (int i = (a); i <= (b); i++)
    #define ro(i, a, b) for (int i = (a); i >= (b); i--)
    const int inf = 0x3f3f3f3f;
    using namespace std;
    const int maxn = 2e5+100;
    vector<int>e[maxn];
    int siz[maxn];
    int ans,n;
    int u,v;
    void getsize(int v,int u){
        siz[v]=1;
        for(int x:e[v]){
            if(x==u)continue;
            getsize(x,v);
            siz[v]+=siz[x];
        }
    }
    void dfs(int v,int u,int t){
        ans=max(ans,t);
        cout<<v<<" "<<u<<" "<<t<<endl;
        for(int x:e[v]){
            if(x==u)continue;
            dfs(x,v,t-2*siz[x]+n);
        }
    }
    int32_t main() {
        scan(n);
        fo(i,1,n-1){
            scann(u,v);
            e[u].pb(v);e[v].pb(u);
        }
        getsize(1,0);
        int t=0;
        fo(i,1,n)t+=siz[i];
        dfs(1,0,t);
        printf("%lld",ans);
        return 0;
    }
    

    [CF816E] 树上背包

    注意最后求答案的时候一定是(dp[1][i][0])或者是(dp[1][i][1])

    因为想要使用优惠券,就必须保证它们的父亲被选了,而点1就是根节点

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int inf = 1e15;
    const int maxn = 5000 + 10;
    int n, b;
    int c[maxn], d[maxn], x[maxn];
    int dp[maxn][maxn][2];
    int sz[maxn];
    vector<int> G[maxn];
    void dfs(int u)
    {
        sz[u] = 1;
        dp[u][1][0] = c[u];
        dp[u][1][1] = c[u] - d[u];
        dp[u][0][0] = 0;
        for(int v:G[u]){
            dfs(v);
            for (int i = sz[u]; i >= 0; i--)
            {
                for (int j = 0; j <= sz[v];j++)
                {
                    dp[u][i + j][0] = min(dp[u][i + j][0], dp[u][i][0] + dp[v][j][0]);
                    dp[u][i + j][1] = min(dp[u][i + j][1], dp[u][i][1] + dp[v][j][0]);
                    dp[u][i + j][1] = min(dp[u][i + j][1], dp[u][i][1] + dp[v][j][1]);
                }
            }
            sz[u] += sz[v];
        }
    }
    int32_t main()
    {
        scanf("%lld%lld", &n, &b);
        scanf("%lld%lld", &c[1], &d[1]);
        for (int i = 2; i <= n;i++)
        {
            scanf("%lld%lld%lld", &c[i], &d[i], &x[i]);
            G[x[i]].push_back(i);
        }
        for (int i = 0; i <= n;i++)
            for (int j = 0; j <= n;j++)
                dp[i][j][0] = dp[i][j][1] = inf;
        dfs(1);
        int ans = 0;
            for (int j = 1; j <= n; j++)
                if(dp[1][j][0]<=b||dp[1][j][1]<=b)
                    ans = max(ans, j);
        cout << ans << endl;
    }
    

    [CF1324E] Maximum White Subtree

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 100;
    
    vector<int> e[maxn];
    int n;
    int a[maxn], ans[maxn], d[maxn];
    void dfs(int u,int fa) {
        d[u] = a[u];
        for(int v:e[u]) {
            if(v==fa)
                continue;
            dfs(v, u);
            if(d[v]>0) {
                d[u] += d[v];
            }
        }
        return;
    }
    
    void dfs2(int u,int fa) {
        ans[u] = d[u];
        for(int v:e[u]) {
            if(v==fa)
                continue;
            //换根操作
            d[u] -= max(0, d[v]);//只有d[v]大于0时,v才可能对u有贡献
            d[v] += max(0, d[u]);//d[u]大于0对v才有贡献
            dfs2(v, u);
            d[v] -= max(0, d[u]);
            d[u] += max(0, d[v]);
        }
    }
    
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n;i++) {
            scanf("%d", &a[i]);
            if(a[i]==0)
                a[i] = -1;
        }
        for (int i = 1; i <= n - 1;i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            e[x].push_back(y);
            e[y].push_back(x);
        }
        dfs(1, 0);
        dfs2(1, 0);
        for (int i = 1; i <= n;i++) {
            printf("%d ", ans[i]);
        }
    }
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 100;
    
    vector<int> e[maxn];
    int n;
    int a[maxn], ans[maxn], d[maxn];
    void dfs(int u,int fa) {
        d[u] = a[u];
        for(int v:e[u]) {
            if(v==fa)
                continue;
            dfs(v, u);
            if(d[v]>0) {
                d[u] += d[v];
            }
        }
        return;
    }
    
    void dfs2(int u,int fa) {
        ans[u] = d[u];
        for(int v:e[u]) {
            if(v==fa)
                continue;
            int t = d[u];
            if(d[v]>0)
                t -= d[v];
            if(t>0)
                d[v] += t;
            dfs2(v, u);
        }
    }
    
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n;i++) {
            scanf("%d", &a[i]);
            if(a[i]==0)
                a[i] = -1;
        }
        for (int i = 1; i <= n - 1;i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            e[x].push_back(y);
            e[y].push_back(x);
        }
        dfs(1, 0);
        dfs2(1, 0);
        for (int i = 1; i <= n;i++) {
            printf("%d ", ans[i]);
        }
    }
    
  • 相关阅读:
    范内瓦·布什发表《诚如所思》,被信息界公认为是信息科学经典之作
    1968年12月9日,恩格尔巴特公开演示了世界上第一个鼠标盒子
    最后一台小型机下线 阿里巴巴如何“去IOE”
    阿里云确认向12306提供了技术协助,负责承接12306网站75%的余票查询流量
    Weka Experimenter(实验者界面) 简解
    数理统计中 极大似然 的含义简介(举例说明)
    Weka Knowledge Flow(知识流界面) 详解
    Weka Explorer(探索者界面) 详解(4)logistic回归和回归算法
    Weka Explorer(探索者界面) 详解(3)决策树算法,分类器评价标准说明
    Weka Explorer(探索者界面) 详解(2)
  • 原文地址:https://www.cnblogs.com/guaguastandup/p/12585244.html
Copyright © 2011-2022 走看看