树上的DP

news2024/11/19 2:35:20

在这里插入图片描述
A C AC AC来的如此之快,让我以为还要再调试几个点(h),本文涉及思路参考:参考文章
嗯,这个题和思路让我对跨父节点的树上链有了一个认识,我们来看一下:
在这里插入图片描述
如果说,我们要对这样的一条链进行 d p dp dp操作,该怎么弄呢?我们需要的是求公共祖先(可以参考我曾经写过的LCA)的思路:
在这里插入图片描述
这样是不是就明白了?有人可能会问,那如果 x x x y y y在一条链上,你还咋用?换个说法,如果 x x x y y y形如下图:
在这里插入图片描述
而我想要找到距离 y y y最近的 x x x的祖先,也就是:
在这里插入图片描述
应该怎么求呢?这个时候就可以利用 x x x来求,还记得我们在求公共祖先的时候,让 x x x y y y到达同一个高度的代码吗?

while(dep[x]!=dep[y])
{
    x=fa[x][lg[dep[x]-dep[y]]-1];
 }

那我们这里就可以看成是让 x x x t a r g e t target target到达同一个高度上,所以可以把上面的代码改写成:

while(dep[x]!=dep[y]-1)
{
    x=fa[x][lg[dep[x]-dep[y]-1]-1];
}

通过 x x x求得 t a r g e t target target,这就是 L C A LCA LCA应用在树形 d p dp dp上的方法;至于本题的状态方程可以写成为:

dp[l][r]=max(dp[l][r-1],max(dp[l+1][r],
            dp[l+1][r-1]+(p[l]==p[r])?2:0));

后记:勤把自己做过的题记录下来还是有好处的,至少在以后啥也不会的时候还能看看…
AC代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int length = 2100;
int fa[length][length];
int lg[length];
int dep[length];
int vis[length];
int dp[length][length];
void dfs(int cur, vector<vector<int>> &edge, int father)
{
	for (int v : edge[cur])
	{
		if (vis[v] == 0 && v != father)
		{
			vis[v] = 1;
			fa[v][0] = cur;
			dep[v] = dep[cur] + 1;
			for (int i = 1; i < dep[v]; i++)
			{
				fa[v][i] = fa[fa[v][i - 1]][i - 1];
			}
			dfs(v,edge,cur);
			vis[v] = 0;
		}
	}
}
int LCA(int x, int y)
{
	//先把x和y提到一个高度上,然后x和y一起往上跳
	//首先让x的高度大于y
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	while (dep[x] != dep[y])
		x = fa[x][lg[dep[x] - dep[y]] - 1];
	if (x == y)return x;//他俩重合在一起了
	for (int i = lg[dep[x]] - 1; i >= 0; i--)
	{
		if (fa[x][i] != fa[y][i])
		{
			x = fa[x][i];
			y = fa[y][i];
		}
	}
	return fa[x][0];
}
int DP(int x, int y,char *p)
{
	if (dp[x][y] != 0)
		return dp[x][y];
	int delta = 0;
	if (p[x] == p[y])
	{
		delta = 2;
	}
	else delta = 0;
	if (dep[x] < dep[y])
	{
		swap(x, y);
	}
	int lca = LCA(x, y);
	if (y == lca)
	{
		//首先找到离y最近的x的祖先节点
		int tmp = x;
		while (dep[y] != dep[x] - 1)
		{
			x = fa[x][lg[dep[x] - dep[y] - 1] - 1];
		}
		swap(tmp, x);
		dp[y][x]=dp[x][y]=max(DP(fa[x][0], y, p), max(DP(tmp, x, p), DP(tmp, fa[x][0], p)+delta));
		return dp[x][y];
	}
	else
	{
		dp[y][x]=dp[x][y]=max(DP(fa[x][0], y,p), max(DP(x, fa[y][0],p), DP(fa[x][0], fa[y][0],p) + delta));
		return dp[x][y];
	}
}
int solve(char *p,int n)
{
	//先给dp数组做初始化
	for (int i = 1; i <= n; i++)
	{
		int yh = fa[i][0];
		if (p[i] == p[yh])
		{
			dp[i][yh] = 2;
			dp[yh][i] = 2;
		}
		else
		{
			dp[i][yh] = 1;
			dp[yh][i] = 1;
		}
		dp[i][i] = 1;
	}
	//然后进行树上的链DP
	int ans = -1;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			ans = max(ans, DP(i, j,p));
		}
	}
	return ans;
}
int main(void)
{
	int t;
	scanf_s("%d", &t);
	for (int i = 1; i < length; i++)
	{
		lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i ? 1 : 0);
	}
	for (int i = 0; i < t; i++)
	{
		memset(fa, 0, sizeof(fa));
		memset(dp, 0, sizeof(dp));
		memset(dep, 0, sizeof(dep));
		int n;
		scanf_s("%d", &n);
		char p[length];
		scanf_s("%s", &p[1], sizeof(p));
		vector<vector<int>> edge(length);
		for (int i = 0; i < n - 1; i++)
		{
			int a, b;
			scanf_s("%d%d", &a, &b);
			edge[a].push_back(b);
			edge[b].push_back(a);
		}
		vis[1] = 1;
		dfs(1, edge, -1);
		int ans=solve(p,n);
		printf("%d\n", ans);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/157292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[GXYCTF2019]BabysqliV3.0

发现我们随便上传一个以后返回的是 alert(Wrong pass); 密码错误 如果上传一个账号永真的话返回 Not this user! 没有这个用户&#xff0c;所以感觉可以使用盲注&#xff0c;对账号进行盲注 可是题目 ascii(substr((select database()),1,1))>1 也不对 最后才知道是…

电脑组装配件知识

目录 1.电脑硬件基础知识 1.1CPU 1.2内存 ​编辑 1.3硬盘 1.4主板 1.5显卡 ​编辑 1.6显示器 1.7电源 1.8机箱 2.电脑硬件搭配及选购 2.1硬件搭配原则 2.2怎样查询软件或游戏配置 2.3配件购买注意事项 2.4搭配一台普通办公电脑 3.电脑组装 1.电脑硬件基础知识 …

软件测试/测试开发 | 一文学会 Appium 环境配置

Appium 是一个开源的、跨平台的测试框架&#xff0c;可以用来测试 Native App、混合应用、移动 Web 应用&#xff08;H5 应用&#xff09;等&#xff0c;也是当下互联网企业实现移动自动化测试的重要工具。Appium 坚持的测试理念&#xff1a; •无需用户对 App 进行任何修改或…

OAuth2.0 开放平台认证授权开发套件 Authmore-Framework 1.0 发布

简介 | Intro 基于 OAuth2.0 协议的开放平台认证授权开发套件, 包含授权服务和开放平台 Docker 镜像&#xff0c;基于 Spring Boot Starter 的资源服务工具包和客户端&#xff08;第三方应用&#xff09;工具包 优点 | Advantages 简洁&#xff1a;专注核心功能 —— 社会化…

剑指offer----C语言版----第十六天----面试题22:链表中的倒数第k个节点

目录 1. 链表中倒数第 k 个节点 1.1 题目描述 1.2 思路一 1.3 思路二&#xff1a; 1.4 总结----代码的鲁棒性 1. 链表中倒数第 k 个节点 原题链接&#xff1a; 剑指 Offer 22. 链表中倒数第k个节点 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/l…

竹制品行业市场运行态势及未来前景分析

2023-2029年中国竹制品行业市场运行态势及未来前景分析报告报告编号&#xff1a;1691644免费目录下载&#xff1a;http://www.cninfo360.com/yjbg/qthy/qt/20230110/1691644.html本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以任何形式复…

基于Power BI的终端消费会员客户价值RFM分析

一、原理&#xff1a;RFM分析 &#xff08;一&#xff09;概念 RFM模型衡量当前客户价值和客户潜在价值的重要工具和手段。通过一个客户的近期购买行为、购买的总体频率以及花了多少钱三个维度来描述该客户价值状况的客户分类模型。 &#xff08;二&#xff09;分析维度 R&a…

使用标量衍射理论和菲涅耳和弗劳恩霍夫衍射的衍射对波动光学进行建模(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 本文使用Matlab对波动光学进行建模。包括使用标量衍射理论和菲涅耳和弗劳恩霍夫衍射的衍射。 &#x1f4da;2 运行结果 &#…

北大硕士LeetCode算法专题课-栈、队列相关问题

算法面试相关专题&#xff1a; 北大硕士LeetCode算法专题课--链表相关问题_ 北大硕士LeetCode算法专题课-查找相关问题_ 北大硕士LeetCode算法专题课-字符串相关问题_ 北大硕士LeetCode算法专题课-数组相关问题_ _ 北大硕士LeetCode算法专题课-基础算法之排序_ 北…

四、Javaweb之Filter、Listener、Ajax、Vue

文章目录12. Filter 和 Listener12.1 Filter快速入门和执行流程12.2 Filter使用细节12.3 Filter案例&#xff1a;登录验证12.4 Listener13. AJAX13.1 AJAX快速入门13.2 AJAX案例13.3 Axios异步框架13.4 JSON13.5 JSON案例SelectAllServlet.javabrand.htmlAddServlet.javaaddBra…

某集团汽车配件电子图册性能分析案例(二)

背景 汽车配件电子图册系统是某汽车集团的重要业务系统。业务部门反映&#xff0c;汽车配件电子图册调用图纸时&#xff0c;出现访问慢现象。 某汽车集团总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原始流量。本次分析重点针对汽车配件电子图…

JDBC简介及原理和使用介绍

JDBC简介及原理和使用介绍JDBC简介 jdbc概述 ​ Java数据库连接&#xff0c;&#xff08;Java Database Connectivity&#xff0c;简称JDBC&#xff09;是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口&#xff0c;提供了诸如查询和更新数据库中数据的方法。 …

WebGL-iTwin.js】实战篇(二):用nodejs代码详解iTwin.js中PhysicalObject生成方法

PhysicalObject 即真实存在的物理对象&#xff0c;比如&#xff1a;电脑、桌子等。在webgl中&#xff0c;我们人眼能看到的模型都是PhysicalObject&#xff0c;由多种几何图元类型构成&#xff0c;如&#xff1a;网格、实体、曲面、曲线&#xff0c;点云等。 其中带索引的多边…

XCTF:cat

打开是一个输入框&#xff0c;要求输入域名&#xff0c;尝试输入baidu.com进行测试 并无任何回显&#xff0c;测试下127.0.0.1本地地址 执行成功&#xff0c;并出现ping命令结果&#xff0c;这里很容易联想到命令注入&#xff0c;尝试进行命令拼接注入 但测试了常用的拼接字…

【5】变量和常量

一、什么是变量 首先我们要理解这么一个概念&#xff0c;在程序的运行过程中所有数据是保存在内存中的&#xff0c;我们代码中想使用这个数据的时候就要从内存中找&#xff0c;而变量的作用类似就是将内存地址保存&#xff0c;之后直接通过这个变量找内存中的数在Go语言中&…

JNI和Ndk开发

按照一下配置&#xff0c;基本能保证demo跑通 1、下载NDK&#xff0c;下载需要的版本 2、下载Cmake版本 3、项目结构&#xff1a;含C源码 4、编写JNI的加载类 public class YjkModel {static {System.loadLibrary("nativ"); //跟CMakeLists.txt 库名一致}public nat…

基于 APISIX 的服务网格方案 Amesh 积极开发中!

作者lingsamuel&#xff0c;API7.ai 云原生技术专家&#xff0c;Apache APISIX Committer。 在云原生快速发展的前提下&#xff0c;服务网格领域也开始逐渐火热。目前阶段&#xff0c;大家所熟知的服务网格解决方案很多&#xff0c;每种产品又各有其优势。因此在面对不同的行业…

python直接赋值、浅拷贝与深拷贝

本文主要参考这篇博文python浅拷贝与深拷贝 基本概念 首先了解python中的一些基本概念 变量&#xff1a;是一个系统表的元素&#xff0c;拥有指向对象的连接空间对象&#xff1a;被分配的一块内存&#xff0c;存储其所代表的值引用&#xff1a;是自动形成的从变量到对象的指…

ECU Extract + OS Task Mapping 步骤

纲要&#xff1a; 通过 Composition里面的Assembly Connection (Intra-ECU Communication)System Extract 里面的SystemDataMapping (Inter-ECU Communication) 已经把SWC的所有Data Element都连接上了&#xff0c;接下来就是把SWC的Runnable给Mapping到对应的OS Task上&…

(三)redis五大数据类型和key

目录 一、redis键&#xff08;key&#xff09;的常用操作 二、redis字符串&#xff08;String&#xff09; 1、简介 2、常用命令 3、数据结构 三、redis列表&#xff08;List&#xff09; 1、简介 2、常用命令 3、数据结构 四、redis集合&#xff08;Set&#xff09;…