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

要记录各种状态的段  a[2][4]

a[0][j]表示以trap为起点一共有j个trap的最优值

a[1][j]表示不以trap为起点一共有j个trap的最优值

dp[x][i][j] 表示以x为根节点的子树从各个叶子到x节点的各状态最优值

每到一个节点 要枚举经过此节点的所有符合要求的段中最优的(需要合并段)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#include<queue>
#include<bitset>
#include<deque>
#include<numeric> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long ll;
typedef unsigned int uint;
typedef pair<int,int> pp;
const double eps=1e-9;
const int INF=0x3f3f3f3f;
const ll MOD=1000000007;
const int N=100005;
int head[N],I;
struct node
{
int j,next;
}edge[N*2];
int value[N],trap[N];
int dp[N][2][4];
int ans,C;
void add(int i,int j)
{
edge[I].j=j;
edge[I].next=head[i];
head[i]=I++;
}
void init(int n)
{
for(int i=0;i<n;++i)
scanf("%d %d",&value[i],&trap[i]);
memset(head,-1,sizeof(head));I=0;
for(int i=1;i<n;++i)
{
int l,r;
scanf("%d %d",&l,&r);
add(l,r);
add(r,l);
}
}
void copyArr(int (*b)[4],int (*a)[4])
{
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
b[i][j]=a[i][j];
}
void clArr(int (*b)[4])
{
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
b[i][j]=-1;
b[0][0]=b[1][0]=0;
}
void update(int (*b)[4],int x)
{
if(trap[x]==0)
{
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
if(b[i][j]!=-1)
b[i][j]+=value[x];
b[0][0]=0;
}else
{
for(int i=0;i<2;++i)
for(int j=3;j>0;--j)
{
if(b[i][j-1]!=-1)
b[i][j]=b[i][j-1]+value[x];
}
b[0][0]=0;
b[1][0]=0;
}
}
void print(int (*b)[4])
{
for(int i=0;i<2;++i)
{
for(int j=0;j<4;++j)
printf("%4d ",b[i][j]);printf("\n");
}printf("\n");
}
void findAns(int (*b)[4],int (*v1)[4],int (*v2)[4],int x)
{
int c=C-trap[x];
int tmp=0;
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
{
for(int l=0;l<2;++l)
for(int r=0;r<4;++r)
{
if(j+r>c) continue;
if(j+r==c)
{
if(i+l==2) continue;
if(i!=l)
{
if(i==0&&j==0) continue;
if(l==0&&r==0) continue;
}
}
if(v1[l][r]!=b[l][r])
tmp=max(tmp,max(0,v1[l][r])+max(0,b[i][j]));
else
tmp=max(tmp,max(0,v2[l][r])+max(0,b[i][j]));
}
}
ans=max(ans,tmp+value[x]);
}
void dfs(int pre,int x,int (*a)[4])
{
int b[2][4];
copyArr(b,a);
update(b,x);
int v1[2][4],v2[2][4];
clArr(v1);clArr(v2);
for(int t=head[x];t!=-1;t=edge[t].next)
{
int l=edge[t].j;
if(l==pre) continue;
dfs(x,l,b);
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
{
v2[i][j]=max(v2[i][j],dp[l][i][j]);
if(v1[i][j]<v2[i][j])
swap(v1[i][j],v2[i][j]);
}
}
copyArr(dp[x],v1);
update(dp[x],x);
for(int i=0;i<2;++i)
for(int j=0;j<4;++j)
{
v2[i][j]=max(v2[i][j],a[i][j]);
if(v1[i][j]<v2[i][j])
swap(v1[i][j],v2[i][j]);
}
findAns(a,v1,v2,x);
for(int t=head[x];t!=-1;t=edge[t].next)
{
int l=edge[t].j;
if(l==pre) continue;
findAns(dp[l],v1,v2,x);
}
}
int main()
{
//freopen("data.in","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d %d",&n,&C);
init(n);
int a[2][4];
clArr(a);
memset(dp,-1,sizeof(dp));
ans=0;
dfs(-1,0,a);
printf("%d\n",ans);
}
return 0;
}

hdu 4616 Game的更多相关文章

  1. HDU 4616 Game (搜索)、(树形dp)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4616 这道题目数据可能比较弱,搜索都可以AC,但是不敢写,哎…… 搜索AC代码: #include & ...

  2. HDU 4616 Game(经典树形dp+最大权值和链)

    http://acm.hdu.edu.cn/showproblem.php?pid=4616 题意:给出一棵树,每个顶点有权值,还有存在陷阱,现在从任意一个顶点出发,并且每个顶点只能经过一次,如果经过 ...

  3. 【 2013 Multi-University Training Contest 2 】

    HDU 4611 Balls Rearrangement 令lcm=LCM(a,b),gcd=GCD(a,b).cal(n,a,b)表示sum(abs(i%a-i%b)),0<=i<n. ...

  4. 【转载】ACM总结——dp专辑

    感谢博主——      http://blog.csdn.net/cc_again?viewmode=list       ----------  Accagain  2014年5月15日 动态规划一 ...

  5. 【DP专辑】ACM动态规划总结

    转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 ...

  6. dp专题训练

    ****************************************************************************************** 动态规划 专题训练 ...

  7. 【DP专辑】ACM动态规划总结(转)

    http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强, ...

  8. dp有哪些种类

    dp有哪些种类 一.总结 一句话总结: 二.dp动态规划分类详解 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. * ...

  9. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

随机推荐

  1. Codeforces708C Centroids 【树形dp】

    题目链接 题意:给定一棵n个结点的树,问:对于每个结点,能否通过删除一条边并添加一条边使得仍是树,并且删除该结点后得到的各个连通分量结点数 <= n/2? 题解:树形dp,两遍dfs,第一遍df ...

  2. [mysql]支持emoji(字符集问题)!

    问题的根源 主要问题就是在字符集,一般解决这种问题都是靠试验.我实验了一通,得出的结论和大家分享一下(如有错误,还望指正): 数据库的字符集 数据库连接的字符集 配置方法 设置数据库的字符集为utf8 ...

  3. Java Performance - 如何调查解决内存问题

    JVM 的内存溢出/不足/OutOfMemoryError/垃圾收集恶性循环是需要解决,又是屡见不鲜的问题. 建议阅读官方的 Troubleshooting Guide for Java SE 6 w ...

  4. 在linux上使用"scp"命令拷贝一个目录到另一台服务器的时候报"not a regular file"错误的解决办法

    今天在linux命令行使用scp命令拷贝一个目录到另一台服务器的时候,报如下错误: [root@hadoop01 ~]# scp flume -r hadoop02:/root/apps flume: ...

  5. xcode 真机调试 failed to get the task for process xxx

    xcode 真机调试 failed to get the task for process xxx 此错误原因是,使用 in house profile 签名了真机调试的证书: 在 target--- ...

  6. The Network Adapter could not establish the connection问题研究

    最近一个项目会报上述错误,但也不是经常发生,所以很难跟踪,影响不是很大,但每次看到日志中这个错误就会不舒服,还是要想办法解决才是. 错误提示信息很明确是网络适配器不能创建连接. 查了很多资料,并且Or ...

  7. C#对象的深拷贝与浅拷贝

    转载自:http://blog.163.com/hr_msn/blog/static/21549405120132250396584/ 深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会 ...

  8. 修复iPhone的safari浏览器上submit按钮圆角bug

    今天在公司写了一个登录页面效果,让我碰到一个怪异的问题——"表单中的input type=submit和input type=reset按钮在iPhone的safari浏览器下圆角有一个bu ...

  9. 百度地图API首页 -- 鼠标经过:类似翻页效果和 类似锚点链接效果

    var timer; $("li").on("mouseover",function(){ clearTimeout(timer); timer=null; $ ...

  10. python 练习 8

    #!/usr/bin/python # -*- coding: utf-8 -*- def ntom(x,size,mod): t=[0]*(size) j=0 while x and j<si ...