hdu 4044 2011北京赛区网络赛E 树形dp ****

专题训练

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 const int MAXN=1010;
  7 const int INF=0x3fffffff;
  8 struct Node
  9 {
 10     int to;
 11     int next;
 12 }edge[MAXN*2];
 13 int tol;
 14 int head[MAXN];
 15 int dp[MAXN][220];
 16 int price[MAXN][60];
 17 int power[MAXN][60];
 18
 19 void init()
 20 {
 21     memset(head,-1,sizeof(head));
 22     tol=0;
 23 }
 24 void add(int a,int b)
 25 {
 26     edge[tol].to=b;
 27     edge[tol].next=head[a];
 28     head[a]=tol++;
 29     edge[tol].to=a;
 30     edge[tol].next=head[b];
 31     head[b]=tol++;
 32 }
 33 int n,m;
 34 int tmp[MAXN];
 35 void dfs(int u,int pre)
 36 {
 37     if(head[u]==-1||(edge[head[u]].to==pre&&edge[head[u]].next==-1))//叶子结点
 38     {//叶子结点的条件不要错了!!!!
 39         for(int i=0;i<=m;i++)dp[u][i]=0;
 40
 41         for(int i=0;i<=m;i++)tmp[i]=dp[u][i];
 42 //因为存在价格为0的点。所以倒序的DP并不能保证只取一件物品
 43         for(int i=m;i>=0;i--)
 44         {
 45             for(int j=1;j<=price[u][0];j++)
 46                if(price[u][j]<=i)
 47                  dp[u][i]=max(dp[u][i],tmp[i-price[u][j]]+power[u][j]);
 48
 49             tmp[i]=dp[u][i];//tmp数组是记录的dp的上一个状态
 50         }
 51         return;
 52     }
 53     for(int i=0;i<=m;i++) dp[u][i]=INF;
 54     for(int i=head[u];i!=-1;i=edge[i].next)
 55     {
 56         int v=edge[i].to;
 57         if(v==pre)continue;
 58         dfs(v,u);
 59         for(int j=m;j>=0;j--)
 60         {
 61             int t=0;
 62             for(int k=0;k<=j;k++)//这里k一定要从0开始。
 63               t=max(t,min(dp[u][j-k],dp[v][k]));
 64             dp[u][j]=t;
 65         }
 66     }
 67
 68
 69     for(int i=0;i<=m;i++)tmp[i]=dp[u][i];
 70     for(int i=m;i>=0;i--)
 71     {
 72         for(int j=1;j<=price[u][0];j++)
 73           if(price[u][j]<=i)
 74              dp[u][i]=max(dp[u][i],tmp[i-price[u][j]]+power[u][j]);
 75         //和上面一样分组背包加了个tmp数组
 76         tmp[i]=dp[u][i];
 77     }
 78 }
 79 int main()
 80 {
 81     int u,v;
 82     int T;
 83     scanf("%d",&T);
 84     while(T--)
 85     {
 86         init();
 87         scanf("%d",&n);
 88         for(int i=1;i<n;i++)
 89         {
 90             scanf("%d%d",&u,&v);
 91             add(u,v);
 92         }
 93         scanf("%d",&m);
 94         for(int i=1;i<=n;i++)
 95         {
 96             scanf("%d",&price[i][0]);
 97             power[i][0]=price[i][0];
 98             for(int j=1;j<=price[i][0];j++)
 99             {
100                 scanf("%d%d",&price[i][j],&power[i][j]);
101             }
102         }
103         dfs(1,0);
104         printf("%d\n",dp[1][m]);
105     }
106     return 0;
107 }
时间: 2024-10-05 23:10:06

hdu 4044 2011北京赛区网络赛E 树形dp ****的相关文章

hdu 4050 2011北京赛区网络赛K 概率dp ***

题目:给出1-n连续的方格,从0开始,每一个格子有4个状态,左右脚交替,向右跳,而且每一步的步长必须在给定的区间之内.当跳出n个格子或者没有格子可以跳的时候就结束了,求出游戏的期望步数 0:表示不能到达这个格子 1:表示左脚跳进这个格子 2:表示右脚跳进这个格子 3:随意哪个脚跳进这个格子,而且下一步随意用哪个脚 dp[i][j] :表示走到第 i 个格子在 j 状态的期望. 当j=1时,你可以走到dp[i+k][2],dp[i+k][3], 当j=2时,你可以走到dp[i+k][1],dp[i

hdu 4041 2011北京赛区网络赛F 组合数+斯特林数 ***

插板法基础知识 斯特林数见百科 1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #define LL long long 6 #define eps 1e-7 7 #define MOD 1000000007 8 using namespace std; 9 int c[2001][2001]={1},stir2[1005][1005]={1};

hdu 4049 2011北京赛区网络赛J 状压dp ***

cl少用在for循环里 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x

hdu 4046 2011北京赛区网络赛G 线段树 ***

还带这么做的,卧槽,15分钟就被A了的题,居然没搞出来 若某位是1,则前两个为wb,这位就是w 1 #include<cstdio> 2 #include<cstring> 3 #define lson l,m,rt<<1 4 #define rson m+1,r,rt<<1|1 5 using namespace std; 6 const int maxn=50010; 7 int n,m,sum[maxn<<2]; 8 char str[ma

hdu 4041 2011北京赛区网络赛B 搜索 ***

直接在字符串上搜索,注意逗号的处理 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 #define pb

hdu 4035 2011成都赛区网络赛E 概率dp ****

太吊了,反正我不会 1 /* 2 HDU 4035 3 4 dp求期望的题. 5 题意: 6 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 7 从结点1出发,开始走,在每个结点i都有3种可能: 8 1.被杀死,回到结点1处(概率为ki) 9 2.找到出口,走出迷宫 (概率为ei) 10 3.和该点相连有m条边,随机走一条 11 求:走出迷宫所要走的边数的期望值. 12 13 设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望.E[1]即为所求. 14 15 叶子结点: 16

hdu 4033 2011成都赛区网络赛 余弦定理+二分 **

二分边长,判断最后内角和是否为2pi,注意l与r的选取,保证能组成三角形 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 10000

hdu 4031 2011成都赛区网络赛A题 线段树 ***

就是不知道时间该怎么处理,想了好久,看了别人的题解发现原来是暴力,暴力也很巧妙啊,想不出来的那种  -_-! 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9

hdu 4036 2011成都赛区网络赛F 模拟 **

为了确保能到达终点,我们需要满足下面两个条件 1.能够到达所有山顶 2.能够在遇到苦土豆时速度大于他 二者的速度可以用能量守恒定律做,苦土豆的坐标可通过三角形相似性来做 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> using na