树状DP

来源:互联网 发布:作文软件 编辑:程序博客网 时间:2024/05/16 05:23

http://acm.hdu.edu.cn/showproblem.php?pid=1561

http://acm.hdu.edu.cn/showproblem.php?pid=1011

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3201

三道几乎一样的树形DP。。。。树形DP+背包。。。。弄了我很久。。积累DP。。也积累rp。。

1011代码:

#include<iostream>
using namespace std;
const int N = 105;
int   dp[N][N],p[N],bug[N],used[N],num[N],n,m;
int   map[N][N];
void dfs(int idx)
{
       for(int i=bug[idx];i<=m;i++)
               dp[idx][i]=p[idx];       
       used[idx]=1;
       for(int i=0;i<num[idx];i++)
       {
              if(used[map[idx][i]]) continue;
              dfs(map[idx][i]);
              for(int j=m;j>=bug[idx];j--)
                   for(int k=1;k<=j-bug[idx];k++)
                          if(dp[idx][j]<dp[idx][j-k]+dp[map[idx][i]][k])
                                dp[idx][j]=dp[idx][j-k]+dp[map[idx][i]][k];
             
       }       
}
int   main()
{
      while(scanf("%d%d",&n,&m)&&n!=-1&&m!=-1)
      {
                   int a ,b ;
                   for(int i=1;i<=n;i++)
                   {
                           scanf("%d%d",&a,&b);
                           bug[i]=((a%20==0)?a/20:a/20+1);
                           p[i]=b;
                   }
                   memset(num,0,sizeof(num));
                   for(int i=1;i<n;i++)
                   {
                           scanf("%d%d",&a,&b);
                           map[a][num[a]++]=b;
                           map[b][num[b]++]=a;
                   }
                   memset(dp,0,sizeof(dp));
                   memset(used,0,sizeof(used));
                   if(m==0)
                   {
                      printf("0/n"); 
                      continue;
                   }
                   dfs(1);
                   printf("%d/n",dp[1][m]);
      }
      return 0;
}

原创粉丝点击