其他分享
首页 > 其他分享> > 偷天换日(树形DP)

偷天换日(树形DP)

作者:互联网

洛谷

比较喜欢(≧∇≦)ノ这个建图
对于叶子节点,直接处理出f[i][j]当前i号节点分j个时间

#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
#define dec(i,l,r) for(int i=l;i>=r;--i)
const int maxm=90005,maxn=1005;
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x; 
}


int T,k,tot,cnt,hd[maxn],f[maxn][maxn];
struct node{
    int to,nt,w;
}e[maxn];
inline void add(int x,int y,int z)
{
 e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].w=z;
} 
inline void GET(int x)
{
    int w,v;
    rd(w);w<<=1; 
    add(x,++cnt,w);
    w=cnt;
    rd(v);
    if(v){
        int vi,wi;
        inc(i,1,v)
        {
            rd(vi),rd(wi);
            dec(j,T-1,0)
            if(j<wi)break;
            else f[w][j]=max(f[w][j],f[w][j-wi]+vi);
        }
    }
    else
    {
        GET(w);
        GET(w);
    }
    
}

inline void DFS(int x)
{
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        DFS(v);
        dec(j,T-1,0)
        inc(k,1,j-e[i].w)
        f[x][j]=max(f[x][j],f[x][j-k-e[i].w]+f[v][k]); 
    }
}
int main()
{
    rd(T);
    GET(0);
    DFS(0);
    int ans=0;
    inc(i,0,T-1)
    ans=max(ans,f[0][i]);
    printf("%d",ans);
    re 0;
}

标签:int,90005,树形,while,偷天换日,getchar,节点,DP,define
来源: https://www.cnblogs.com/lsyyy/p/11285584.html