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竞赛中的重点,同时又是难点,因为该算法时间 ...
随机推荐
- Promise A 规范的一个简单的浏览器端实现
简单的实现了一个promise 的规范,留着接下来模块使用.感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码 主要是Then 函数.回调有点绕人. !(function(win) { fu ...
- poj1927Area in Triangle
链接 物理渣只能搜题解了.. 分三种情况 1.len>=a+b+c 2.len<内切圆半径 圆的面积是最大的 -->以len为周长的圆 3.看这篇http://blog.sina.c ...
- (四)802.1Q VLAN
- [html] src与href的区别
src用于替换当前元素,href用于在当前文档和引用资源之间确立联系. src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置:在请求src资源时会将其指向的资源下 ...
- Bootstrap的标题
一.定义标题 Bootstrap和普通的HTML页面一样,定义标题都是使用标签<h1>到<h6>,只不过Bootstrap覆盖了其默认的样式,使用其在所有浏览器下显示的效果一样 ...
- jquery中html(), text(),val()区别(zhuan)
https://zhidao.baidu.com/question/307317838.html http://www.cnblogs.com/aqbyygyyga/archive/2011/11/0 ...
- vim Project
VIM是Linux和Unix下常用的文本编辑工具,在编写代码和阅读代码中经常使用. 但VIM进行代码项目管理时,没有IDE集成开发工具方便,现在提供一个VIM插件Project,可以对代码项目进行简单 ...
- C# 中的弱引用 WeakReference
C#中的弱引用(WeakReference) 我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的.我们能不能同时保持对对象的引用,而又可以让GC需要的时候回收这个对象呢?.NET ...
- C++ 迭代器介绍 [转摘]
转摘地址为:http://blog.chinaunix.net/uid-20773165-id-1847758.html 迭代器 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭 ...
- 各种U启网启什么的都是浮云
对于支持BIOS的电脑,优盘启动,网络启动的各种方案感觉都是浮云,从硬盘启动PE进行维护才是最可靠的.不点在开发wee的过程中给了我们很多维护的灵感,不用费劲地折腾fbinst/U+/量产/PXE/I ...