zoukankan      html  css  js  c++  java
  • CF1249F Maximum Weight Subset (树形dp)

    这道题的状态可以设计为f[i][j]表示在以i为根的子树上,深度最小为j的最大值。这个深度是相对于子树的深度

    因此我们枚举深度去更新当前子树答案,在第一次更新的时候,先去求深度恰好为j的答案,之后倒序取一遍max就是答案

    如果深度为0,就是选择根节点,那么只要把所有子树中>=k的位置选进来就行(这里的k已经先行+1)

    如果深度不为0,那么我们就去枚举子树,表示深度为j的点在哪个子树上。但是在这个更新中,其实我们求取的并不一定就是物理意义为深度恰好为j,但这并不影响答案

    ,之后只需要对其他子树枚举距离大于等于k并且深度不超过j的答案叠加即可,可能有人会有疑惑说其他子树之前是否会距离不足k,这是显然不可能的,因为我们有max约束,具体可以看代码领会

    因为我们枚举了深度为j的在哪个子树,所以我们枚举完了所有的答案

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=2e5+10;
    int a[N];
    vector<int> g[N];
    int h[N],e[N],ne[N],idx;
    int f[500][500];
    int n,k;
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs(int u,int fa){
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            dfs(j,u);
        }
        for(i=0;i<201;i++){
            if(i==0){
                f[u][0]=a[u];
                for(int j=h[u];j!=-1;j=ne[j]){
                    int v=e[j];
                    if(v==fa)
                        continue;
                    f[u][0]+=f[v][max(0,k-1)];
                }
            }
            else{
                for(int j=h[u];j!=-1;j=ne[j]){
                    int v=e[j];
                    if(v==fa)
                        continue;
                    int dis=f[v][i-1];
                    for(int x=h[u];x!=-1;x=ne[x]){
                        int d=e[x];
                        if(d==v||d==fa)
                            continue;
                        dis+=f[d][max(i-1,k-i-1)];
                    }
                    f[u][i]=max(f[u][i],dis);
                }
            }
        }
        for(i=201;i>=0;i--)
            f[u][i]=max(f[u][i+1],f[u][i]);
    }
    int main(){
        ios::sync_with_stdio(false);
        int i,j;
        cin>>n>>k;
        k++;
        memset(h,-1,sizeof h);
        for(i=1;i<=n;i++)
            cin>>a[i];
        for(i=1;i<n;i++){
            int u,v;
            cin>>u>>v;
            add(u,v);
            add(v,u);
        }
        dfs(1,-1);
        cout<<f[1][0]<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    6.Java中的链表数据结构ListNode
    5.把字符串转换成整数
    vue-cli3预设preset记录
    vue2.0用法技巧汇总
    typeof
    js对象注意
    本地搭建sass运行环境
    安卓手机移动端Web开发调试之Chrome远程调试(Remote Debugging)
    Vue中引入jquery方法
    移动端开发问题及技巧汇总
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13500966.html
Copyright © 2011-2022 走看看