博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CCPC-Wannafly Winter Camp Day1 流流流动 (树形dp)
阅读量:5091 次
发布时间:2019-06-13

本文共 2709 字,大约阅读时间需要 9 分钟。

题目描述

 

喜欢数学的wlswls最近被萎住了。

现在他一共有1...n1...n这么多数字,取数字ii会得到f[i]f[i]的收益。数字之间有些边,对于所有的i(i != 1)i(i!=1),若ii为奇数,则ii与3i+13i+1之间有边,否则ii与i/2i/2之间有边。如果一条边的两个顶点xyxy都被取了,那么会失去d[min(x, y)]d[min(x,y)]的价值。请问wlswls怎么取,才能使得收益最大?

 

 
 

输入描述

 

第一行一个整数nn。

接下来一行nn个整数表示ff。

接下来一行nn个整数表示dd。

1 \leq n \leq 1001n100

1 \leq f[i], d[i] \leq 10001f[i],d[i]1000

 

输出描述

 

输出一个整数表示答案。

 

样例输入 1 

210 10 1 2

样例输出 1

19 思路: 根据题目给的建边条件,建边后会形成一个森林,然后把森林转化为一个0为根节点的树,随后进行树形dp。 定义状态: dp[u][0/1]  0为 第u个节点的子树中不取第u个节点的最多利益值,        1为第u个节点的子树中取第u个节点的最多利益值, 常规的树形dp套路, dp[u][0]+=max(dp[v][0],dp[v][1]); dp[u][1]+=max(dp[v][0],dp[v][1]-d[min(u,v)]);// 一个边上两个节点都取的话,要减去对应的值。 最后max(dp[0][0],dp[0][1])就是我们的答案值。 细节见代码:
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ALL(x) (x).begin(), (x).end()#define rt return#define dll(x) scanf("%I64d",&x)#define xll(x) printf("%I64d\n",x)#define sz(a) int(a.size())#define all(a) a.begin(), a.end()#define rep(i,x,n) for(int i=x;i
#define pll pair
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define MS0(X) memset((X), 0, sizeof((X)))#define MSC0(X) memset((X), '\0', sizeof((X)))#define pb push_back#define mp make_pair#define fi first#define se second#define eps 1e-6#define gg(x) getInt(&x)#define db(x) cout<<"== [ "<
<<" ] =="<
v[maxn];int w;void dfs(int u, int pre){ // cout<
<<" "<
<
> n; repd(i, 1, n) { cin >> f[i]; } repd(i, 1, n) { cin >> d[i]; } repd(i, 2, n) { if (i & 1) { if (3 * i + 1 <= n) { v[i].push_back(3 * i + 1); v[3 * i + 1].push_back(i); mer(i, 3 * i + 1); } } else { v[i].push_back(i / 2); v[i / 2].push_back(i); mer(i, i / 2); } } repd(i, 1, n) { if (pre[i] == 0) { v[0].push_back(i); v[i].push_back(0); } } dfs(0, 0); cout << max(dp[0][0], dp[0][1]) << endl; return 0;}inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } }}

 

 

转载于:https://www.cnblogs.com/qieqiemin/p/10907090.html

你可能感兴趣的文章
【题解】[P4178 Tree]
查看>>
Mongo自动备份
查看>>
cer证书签名验证
查看>>
synchronized
查看>>
【深度学习】caffe 中的一些参数介绍
查看>>
Python-Web框架的本质
查看>>
QML学习笔记之一
查看>>
App右上角数字
查看>>
从.NET中委托写法的演变谈开去(上):委托与匿名方法
查看>>
小算法
查看>>
201521123024 《java程序设计》 第12周学习总结
查看>>
新作《ASP.NET MVC 5框架揭秘》正式出版
查看>>
IdentityServer4-用EF配置Client(一)
查看>>
WPF中实现多选ComboBox控件
查看>>
读构建之法第四章第十七章有感
查看>>
Windows Phone开发(4):框架和页 转:http://blog.csdn.net/tcjiaan/article/details/7263146
查看>>
Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)【转】
查看>>
python asyncio 异步实现mongodb数据转xls文件
查看>>
TestNG入门
查看>>
【ul开发攻略】HTML5/CSS3菜单代码 阴影+发光+圆角
查看>>