题意:
一个游戏的迷宫是一颗树型结构..树上的点代表了房间..每个房间里宝藏..有些房间里有陷阱..现在开始游戏..咱有C条命..若进入了有trap的房间..就会掉一条命..没有命了就Game Over了...可以从这颗树中任意的点开始沿着边走...问能获得的最多宝藏...
题解:
练习赛的时候..用2维来做...果断跪了...这道题用两个维度是无法将所有的状态表示出来的...因为这道题有别于裸求树中某条链的最大价值...从某种程度上来说路径是有向的...就像第一个样例...1可以更新到2..2不能更新到0(因为到了2...拿了宝藏就Game Over了)..但是从0可以更新到2...
可以发现路径有向的情况为路径上有exactly C个trap....而一条合法链上出现C个trap当且仅当其至少有一头(起点 or 终点)为有trap的点...那么状态转化为三维的表示:
dp[node][trap_num][k]...代表以node为一头的链..其陷阱个数为trap_num...链的另一个端点是否为有trap..如此..还是用传统的树形DP来解决了...统计答案的时候保证两头至少有一个为有trap的就行了...
WA了几才过..原因是初始化..因为更新时实际上是要判断是否有值可以更新过来的...而我的dp值初始化为0...导致转移出了些问题....如果省去一些转移判断..dp值的初始化还是定义为负无穷大吧...这些细节一定要注意...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<queue> #include<stack> #include<set> #include<map> #include<algorithm> #define ll long long #define eps 1e-5 #define oo 1000000007 #define pi acos(-1.0) #define MAXN 50005 #define MAXM 2000005 using namespace std; struct node { int w,c; }P[MAXN]; struct LINE { int x,y,next; }line[2*MAXN]; int Lnum,_next[MAXN],dp[MAXN][5][2],C,ans; void addline(int x,int y) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y; } void dfs(int x,int father) { int y,k,i,j; dp[x][P[x].c][P[x].c]=P[x].w; for (k=_next[x];k;k=line[k].next) { y=line[k].y; if (y==father) continue; dfs(y,x); for (i=0;i<=C;i++) for (j=0;j<=C-i;j++) { ans=max(ans,dp[x][i][0]+dp[y][j][1]); ans=max(ans,dp[x][i][1]+dp[y][j][0]); ans=max(ans,dp[x][i][1]+dp[y][j][1]); if (i+j==C) continue; ans=max(ans,dp[x][i][0]+dp[y][j][0]); } //--------------------------------------------------------------- for (i=0;i<=C;i++) { dp[x][i+P[x].c][0]=max(dp[x][i+P[x].c][0],P[x].w+dp[y][i][0]); dp[x][i+P[x].c][1]=max(dp[x][i+P[x].c][1],P[x].w+dp[y][i][1]); } } return; } int main() { int T,N,i; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&T); while (T--) { scanf("%d%d",&N,&C); for (i=0;i<N;i++) scanf("%d%d",&P[i].w,&P[i].c); memset(_next,0,sizeof(_next)); Lnum=0; for (i=1;i<N;i++) { int x,y; scanf("%d%d",&x,&y); addline(x,y),addline(y,x); } memset(dp,-0x3f,sizeof(dp)); ans=0; dfs(0,-1); printf("%d\n",ans); } return 0; }