树形 DP

洛谷 P1352 没有上司的舞会

树形 DP 模板题。

#include <bits/stdc++.h>
using namespace std;
const int N=6010;
struct node{
    int v,next;
}e[N];
int n,l,k,cnt;
bool v[N];
int head[N],f[N][2];
void DFS(int u){
    v[u]=true;
    for(int i=head[u];i;i=e[i].next){
        if(v[e[i].v]) continue; //一个员工可能不止一个直接上司
        DFS(e[i].v);
        f[u][0]+=max(f[e[i].v][0],f[e[i].v][1]);
        f[u][1]+=f[e[i].v][0];
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&f[i][1]);
    for(int i=1;i<=n-1;++i){
        scanf("%d%d",&l,&k);
        v[l]=true;
        e[++cnt].v=l;
        e[cnt].next=head[k];
        head[k]=cnt;
    }
    for(int i=1;i<=n;++i)
        if(!v[i]){
            memset(v,false,sizeof(v));
            DFS(i);
            printf("%d\n",max(f[i][0],f[i][1]));
            return 0;
        }
}

AcWing 10. 有依赖的背包问题

此题是背包型的树形DP。

AC 代码:

#include <iostream>
using namespace std;
const int N=110;
struct node{
    int v,next;
}e[N];
int n,c,p,cnt,root;
int v[N],w[N],head[N],f[N][N];
void DFS(int u){
    //先为u节点留个位置,然后枚举所有状态体积小于等于c-v[u]的所有子节点们能够获得的最大价值
    for(int i=head[u];i;i=e[i].next){
        DFS(e[i].v);
        for(int j=c-v[u];j>=0;--j)
            for(int k=0;k<=j;++k)
                f[u][j]=max(f[u][j],f[u][j-k]+f[e[i].v][k]);
    }
    //最后选上第u件物品
    for(int i=c;i>=v[u];--i) f[u][i]=f[u][i-v[u]]+w[u];
    for(int i=0;i<v[u];++i) f[u][i]=0; //清空没选上u的所有状态
}
int main(){
    scanf("%d%d",&n,&c);
    for(int i=1;i<=n;++i){
        scanf("%d%d%d",&v[i],&w[i],&p);
        if(p==-1) root=i;
        else{
            e[++cnt].v=i;
            e[cnt].next=head[p];
            head[p]=cnt;
        }
    }
    DFS(root);
    printf("%d\n",f[root][c]);
    return 0;
}

AcWing 1075. 数字转换

一道简单的模板题,其中求 f 的这一步是重点,最后转化为了求树的直径。

AC 代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;
const int N=5e4+10;
int n,f[N],d1[N],d2[N],ans;
vector<int>e[N];
void dfs(int u,int fa){
    for(int &v:e[u]){
        if(v==fa) continue;
        dfs(v,u);
        if(d1[v]+1>d1[u]) d2[u]=d1[u],d1[u]=d1[v]+1;
        else if(d1[v]+1>d2[u]) d2[u]=d1[v]+1;
    }
    ans=max(ans,d1[u]+d2[u]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) f[i]=1;
    for(int i=2;i<=n;++i)
        for(int j=2;j*i<=n;++j)
            f[j*i]+=i;
    for(int i=2;i<=n;++i)
        if(f[i]<i){
            e[i].push_back(f[i]);
            e[f[i]].push_back(i);
        }
    dfs(1,1);
    printf("%d\n",ans);
    return 0;
}
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Previous
Next