【树形背包】洛谷P2014 选课

链接

https://www.luogu.org/problem/show?pid=2014


大意

给定一些课程,学一个课程有先修课,选修课至多一个,给定学习每个课程的学分和最多能学习课程的数量,求最高学分


思路

树形 DP D P

由于有对学习课程数量的限制,可以想到将背包与树形 dp d p 结合起来,就可以轻松 A A 掉啦


代码

#include
#include
#include
#include
using namespace std;int n,m,f[2005][2005],head[2005],next[2005];
inline int dp(register int x)
{
    if(head[x]==-1) return 0;
    int sum=0;
    for(register int i=head[x];~i;i=next[i])
    {
        int t=dp(i);
        sum+=t+1;
        for(register int j=sum;j>=0;j--)
         for(register int k=0;k<=j-1;k++)
          f[x][j]=max(f[x][j],f[x][j-k-1]+f[i][k]);
    }
    return sum;
}
signed main()
{
    scanf("%d%d",&n,&m);
    memset(head,-1,sizeof(head));
    for(register int i=1,a;i<=n;i++)
    {
        scanf("%d%d",&a,&f[i][0]);
        next[i]=head[a];
        head[a]=i;//简易邻接表
    }
    dp(0);
    printf("%d",f[0][m]);
}

你可能感兴趣的:(dp)