codevs 1378 选课 (树形DP)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,son[310][2],f[310][310],v[310],ans,falg;
int init()
{
    int x=0;char s;s=getchar();
    while(s<'0'||s>'9')s=getchar();
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x;
}
int DP(int p,int x)
{
    if(x==0||(p==0&&falg==1))return 0;
    falg=1;
    if(f[p][x])return f[p][x];
    
    int maxx=0;
    f[p][x]=v[p];
    for(int i=1;i<=x;i++)
      {
        maxx=max(maxx,DP(son[p][1],x-i)+v[p]+DP(son[p][2],i-1));
        maxx=max(maxx,DP(son[p][2],x));
      } 
    if(maxx>f[p][x])f[p][x]=maxx;
    return f[p][x];
}
int main()
{
    n=init();m=init();
    int x,y;
    for(int i=1;i<=n;i++)
      {
          x=init();y=init();
        v[i]=y;
          if(son[x][1]==0)//左孩子空 直接放上 
            {
                son[x][1]=i;
                continue;
          }
        int fa=son[x][1];//左孩子不空 i要放到左孩子的右孩子上 
        while(son[fa][2])fa=son[fa][2];//一直放到空的地方 
          son[fa][2]=i;
      }
    printf("%d\n",DP(0,m+1));//多加一个节点0 把森林变为树 同时科目数+1 
}

 

posted @ 2016-05-13 22:23  一入OI深似海  阅读(259)  评论(0编辑  收藏  举报