选课 树形dp+路径输出

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 2010
using namespace std;
int n,m,v[maxn],sum[maxn],son[maxn][maxn],s[maxn][3],f[maxn][maxn];
bool falg[maxn];
int Dfs(int k,int p)
{
    if(k==0&&p!=m||p==0)return 0;
    if(f[k][p])return f[k][p];
    int s1=0,s2=0,lc=son[k][1],rc=son[k][2];
    if(rc)s1=Dfs(rc,p);
    for(int i=0;i<=p-1;i++)
      s2=max(s2,Dfs(lc,i)+Dfs(rc,p-i-1)+v[k]);
    return f[k][p]=max(s1,s2);
}
void Path(int k,int p)
{
    int lc=son[k][1],rc=son[k][2];
    if(rc&&f[rc][p]==f[k][p])
      {
          falg[k]=0;Path(rc,p);return;
      }
    for(int i=0;i<=p-1;i++)
      {
          if(f[k][p]==f[lc][i]+f[rc][p-i-1]+v[k])
            {
                falg[k]=1;Path(lc,i);
            Path(rc,p-i-1);return;
          }
      }
}
int main()
{
    freopen("course.in","r",stdin);
    freopen("course.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x,y;m++;
    for(int i=1;i<=n;i++)
      {
          scanf("%d%d",&x,&y);v[i]=y;
          if(son[x][1]==0)son[x][1]=i;
          else 
            {
                int now=son[x][1];
                while(son[now][2])now=son[now][2];
                son[now][2]=i;
          }
      }
    int ans=Dfs(0,m);
    printf("%d
",ans);
    Path(0,m);
    for(int i=1;i<=n;i++)
      if(falg[i])
        printf("%d
",i);
    return 0;
}
原文地址:https://www.cnblogs.com/yanlifneg/p/5730460.html