hdu 4616 Game
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的更多相关文章
- HDU 4616 Game (搜索)、(树形dp)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4616 这道题目数据可能比较弱,搜索都可以AC,但是不敢写,哎…… 搜索AC代码: #include & ...
- HDU 4616 Game(经典树形dp+最大权值和链)
http://acm.hdu.edu.cn/showproblem.php?pid=4616 题意:给出一棵树,每个顶点有权值,还有存在陷阱,现在从任意一个顶点出发,并且每个顶点只能经过一次,如果经过 ...
- 【 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. ...
- 【转载】ACM总结——dp专辑
感谢博主—— http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 动态规划一 ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
- dp专题训练
****************************************************************************************** 动态规划 专题训练 ...
- 【DP专辑】ACM动态规划总结(转)
http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强, ...
- dp有哪些种类
dp有哪些种类 一.总结 一句话总结: 二.dp动态规划分类详解 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. * ...
- (转)dp动态规划分类详解
dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...
随机推荐
- Git 的origin和master分析 push/diff/head(转)
1.origin/master : 一个叫 origin 的远程库的 master 分支 2.HEAD指向当前工作的branch,master不一定指向当前工作的branch 3.git push ...
- 用JS打开网页时自动更改css样式,可用于处理浏览器兼容
代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- Java中JTree的简单案例
package ch12; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; /** * Created by ...
- linux之echo命令
linux的echo命令, 在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的, 因此有必要了解下echo的用法 echo命令的功能是在显示器上显示一段文字,一般起到一个提示 ...
- 最大的LeftMax与rightMax之差绝对值
这两天去 牛客网 混了下,遇到的几道题都很有意思,尤其是今晚这道,比赛时不会做,后来看了别人的代码才突然想通的,题目链接: 最大的LeftMax与rightMax之差绝对值,大意是: 想了一晚都没想出 ...
- bignum 大数模板
今天无意间看到一个很好的大数模板,能算加.减.乘.除等基本运算,但操作减法的时候只能大数减小数,也不支持负数,如果是两个负数的话去掉符号相加之后再取反就可以了,一正一负比较绝对值大小,然后相减.我借用 ...
- Node.js superagent 采集 URL 编码问题
今天在用Node学习采集的时候遇到一个问题,如这个链接地址 http://www.meishij.net/胡萝卜 就是用浏览器的方式访问链接可以打开,但用superagent 去模拟请求,就请求不到 ...
- D3.js 简介和安装
一.What´s D3.js D3.js是一种数据操作类型的javascript库(也可视其为插件):结合HTML,SVG和CSS,D3可以图形化的,生动的展现数据. D3 的全称是(Data-Dri ...
- graph-tool 练习
如何使用graph-tool模块,如何导入?如何使用graph,使用其算法? 如何使用Boost Graph库,安装,测试? 1 创建和操纵图 如何创建空图? g = Graph() 如何精准的创建有 ...
- Django开发博客- 三部曲
其实在django中实现一个功能只需要三个步骤即可,这里我姑且叫它三部曲. 这三部曲就是: 定义urls映射 定义views 定义templates 什么是URL? URL就算一个WEB地址,你在浏览 ...