zoukankan      html  css  js  c++  java
  • 背包类树形DP 选课题解

    题目传送门;

    我觉得题目给出0节点作为虚拟课程,也避免了我们要去想将若干个森林建成一棵树;将N个节点的森林建成了N+1条边的树;

    其次,我们对这个题进行一个分析;

    很容易想到F【x,t】表示以x为根的子树中,选择t门课程所获得得最高学分;

    在x的子树中选择节点y,再以y为根的子树中,选择c_i门课程,保证Σc_i = t - 1;

    初始状态,t=0时,F【x,t】=0;

    通过分析状态转移方程,该方程实际上是一个分组背包模型,第i组的第j个物品体积为j,价值为F[y,j],背包总容积t-1;

    我们要从每组中选择不超过1个物品(每个子节点y都只能选择一个状态转移到x),在选择总物品不超过t-1的前提下,学分最大;

    是背包与树形DP的结合;

     

    #include<bits/stdc++.h>
    using namespace std;
    int lin[1000],tot,n,m,x,f[400][400],s[400];
    template<typename T>inline void read(T &x)
    {
        x=0;T f=1,ch=getchar();
        while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
        while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
        x*=f;
    }
    struct gg {
        int y,next;
    }a[2000];
    inline void add(int x,int y) {
        a[++tot].y=y;
        a[tot].next=lin[x];
        lin[x]=tot;
    } 
    inline void dp(int x) {
        f[x][0]=0;
        for(int i=lin[x];i;i=a[i].next) {
            int y=a[i].y;
            dp(y);
            //倒序循环当前选课总门数,或者背包的总体积; 
            for(int t=m;t>=0;--t) {
                //循环更深子树上的选课门数(组内物品);
                //此处倒序是为了正确处理组内体积为0的物品,这样可以从初始状态f【x,0】转移;
                for(int j=t;j>=0;--j) {
                    if(t-j>=0) {
                        f[x][t]=max(f[x][t],f[x][t-j]+f[y][j]);
                    }
                }
            }
        }
        if(x!=0) {//x!=0,选修x本身需要占用1节课,获得相应的学分; 
            for(int t=m;t>0;t--) 
                f[x][t]=f[x][t-1]+s[x];
        }
    }
    int main() {
        read(n);read(m);
        for(int i=1;i<=n;i++) {
            read(x);
            add(x,i);
            read(s[i]);
        }
        dp(0);
        cout<<f[0][m]<<endl;
        return 0;
    }
  • 相关阅读:
    hdu2302(枚举,大数取模)
    hdu2108(判断凸多边形)
    Codeforces Round #324 (Div. 2) C (二分)
    hdu1798(圆的位置关系)
    hdu1722(gcd)
    alias命令(使用命令别名)
    关于Linux环境变量
    poj1988(并查集)
    Linux基本命令
    Pandas数据规整
  • 原文地址:https://www.cnblogs.com/Tyouchie/p/10830072.html
Copyright © 2011-2022 走看看