zoukankan      html  css  js  c++  java
  • [jzoj 5661] 药香沁鼻 解题报告 (DP+dfs序)

    interlinkage:

    https://jzoj.net/senior/#contest/show/2703/0

    description:

    solution:

    • 注意到这本质就是一个背包,只是选了一个点就必须把它到根节点的所有的点都选上
    • 考虑如何转移这个背包,发现一个点要么转移到$dfs$序比它大$1$的点上,要么转移到比这个点子树中$dfs$序最大的点的$dfs$序大$1$的点上
    • 前者表示这条链继续选,后者表示放弃这条链
    • 易得所有的状态都会被转移到
    • 这是一个很经典的问题

    code:

    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    const int N=5e3+15;
    const int M=1e4+15;
    int n,p,ans,tot,tim;
    int w[N],f[N],v[N],head[N],dp[N][M],id[N],st[N],ed[N];
    struct EDGE
    {
        int to,nxt;
    }edge[N<<1];
    inline int read()
    {
        char ch=getchar();int s=0,f=1;
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
        return s*f;
    }
    void add(int u,int v)
    {
        edge[++tot]=(EDGE){v,head[u]};
        head[u]=tot;
    }
    void dfs(int x)
    {
        st[x]=++tim;id[tim]=x;
        for (int i=head[x];i;i=edge[i].nxt)
            dfs(edge[i].to);
        ed[x]=tim;
    }
    int main()
    {
        freopen("medicine.in","r",stdin);
        freopen("medicine.out","w",stdout);
        n=read();p=read();
        w[1]=read();f[1]=read();v[1]=read();
        for (int i=2;i<=n;i++)
        {
            w[i]=read();f[i]=read();v[i]=read();
            add(f[i],i);
        }
        dfs(1);
        memset(dp,-0x3f,sizeof(dp));
        dp[1][0]=0;
        for (int i=1;i<=tim;i++)
        {
            int x=id[i];
            for (int j=0;j<=p;j++) if (dp[i][j]>=0)
            {
                if (j+w[x]<=p) dp[i+1][j+w[x]]=max(dp[i+1][j+w[x]],dp[i][j]+v[x]);
                dp[ed[x]+1][j]=max(dp[ed[x]+1][j],dp[i][j]);
                ans=max(ans,dp[i][j]);
            }
        }
        for (int i=0;i<=p;i++) ans=max(ans,dp[tim+1][i]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    cafebabe go入门练习003:常量与iota
    go入门练习002:查找重复的行
    go入门练习001:打印命令行输入
    go入门-002-程序结构
    [ES6深度解析]10:Generators 续集
    [JavaScript初级面试]17. 运行环境
    [JavaScript初级面试]16. 运行环境
    [JavaScript初级面试]10. WEB API
    [JavaScript初级面试]8. WEB API
    [JavaScript初级面试]7. WEB API
  • 原文地址:https://www.cnblogs.com/xxzh/p/10668919.html
Copyright © 2011-2022 走看看