【c++笔试强训】(第四十一篇)

目录

体操队形(DFS+枚举)

题目解析

讲解算法原理

编写代码

⼆叉树中的最⼤路径和(树形dp)

题目解析

讲解算法原理

编写代码


体操队形(DFS+枚举)

题目解析

1.题目链接:登录---专业IT笔试面试备考平台_牛客网

2.题目描述

题目描述

dddddd作为体操队队长,在给队员们排队形,体操队形为一个单独的纵列,体操队有nnn个同学,标号为1∼n1\sim n1∼n,对于i(1≤i≤n)i(1≤i≤n)i(1≤i≤n)号队员,会有一个诉求(1≤a[i]≤n)(1≤a[i]≤n)(1≤a[i]≤n),表示他想排在a[i]a[i]a[i]号队员前面,当a[i]=ia[i]=ia[i]=i时,我们认为他没有位置需求,随便排哪儿都行,dddddd想知道有多少种队形方案,可以满足所有队员的要求。

输入描述:

读入第一行一个数字n(2≤n≤10)

第二行n个数字,表示a[i],保证1≤a[i]≤n

输出描述:

输出一行,表示方案数

示例1

输入

3 1 1 2

3

1 1 2

输出

1

1

讲解算法原理

解法:
算法思路:

画出决策树,注意剪枝策略~

编写代码

c++算法代码:

cpp 复制代码
#include <iostream>
using namespace std;
const int N = 15;
int ret;
int n;
bool vis[N];
int arr[N];
void dfs(int pos)
{
 if(pos == n + 1) // 找到⼀种合法⽅案 {
 ret++;
 return;
 }
 
 for(int i = 1; i <= n; i++)
 {
 if(vis[i]) continue; // 当前 i 已经放过了 - 剪枝
 if(vis[arr[i]]) return; // 剪枝
 vis[i] = true; // 相当于放上 i 号队员 dfs(pos + 1);
 vis[i] = false; // 回溯- 还原现场 }
}
int main()
{
 cin >> n;
 for(int i = 1; i <= n; i++) cin >> arr[i];
 
 dfs(1);
 
 cout << ret << endl;
 
 return 0;
}

java算法代码:

java 复制代码
mport java.util.*;
public class Main
{
 public static int N = 15; public static int n, ret; public static boolean[] vis = new boolean[N]; public static int[] arr = new int[N];  public static void dfs(int pos) {
 if(pos == n + 1) // 找到⼀种合法情况 {
 ret++;
 return;
 }
 
 for(int i = 1; i <= n; i++)
 {
 if(vis[i] == true) continue; // 剪枝 - i 号队员已经放过了
 if(vis[arr[i]]) return; // 剪枝
 vis[i] = true; // 相当于已经放上 i 号队员 dfs(pos + 1);
 vis[i] = false; // 回溯 - 恢复现场 } } 
 public static void main(String[] args)
 {
 Scanner in = new Scanner(System.in); n = in.nextInt(); for(int i = 1; i <= n; i++)
 {
 arr[i] = in.nextInt();
 }
 
 dfs(1);
 
 System.out.println(ret);
 }
}

⼆叉树中的最⼤路径和(树形dp)

题目解析

1.题目链接:二叉树中的最大路径和_牛客题霸_牛客网

2.题目描述

描述

二叉树里面的路径被定义为:从该树的任意节点出发,经过父=>子或者子=>父的连接,达到任意节点的序列。

注意:

1.同一个节点在一条二叉树路径里中最多出现一次

2.一条路径至少包含一个节点,且不一定经过根节点

给定一个二叉树的根节点root,请你计算它的最大路径和

例如:

给出以下的二叉树,

最优路径是:2=>1=>3,或者3=>1=>2,最大路径和=2+1+3=6

数据范围:节点数满足 1 \le n \le 10^51≤n≤105 ,节点上的值满足 |val| \le 1000∣val∣≤1000

要求:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

示例1

输入:

{1,2,3}

复制返回值:

6

复制

示例2

输入:

{-20,8,20,#,#,15,6}

复制返回值:

41

复制说明:

其中一条最大路径为:15=>20=>6,路径和为15+20+6=41

示例3

输入:

{-2,#,-3}

返回值:

-2

讲解算法原理

解法:
算法思路:

树形dp:

a. 左⼦树收集:以左⼦树为起点的最⼤单链和;b. 右⼦树收集:以右⼦树为起点的最⼤单链和;

c. 根节点要做的事情:整合左右⼦树的信息,得到经过根节点的最⼤路径和;

d. 向上返回:以根节点为起点的最⼤单链和

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
public:
 int ret = -1010;
 int maxPathSum(TreeNode* root) 
 {
 dfs(root);
 return ret;
 }
 int dfs(TreeNode* root)
 {
 if(root == nullptr) return 0;
 int l = max(0, dfs(root->left));// 左⼦树的最⼤单链和 int r = max(0, dfs(root->right)); // 右⼦树的最⼤单链和 // 经过root的最⼤路径和
 ret = max(ret, root->val + l + r);
 return root->val + max(l, r);
 }
};

java算法代码:

java 复制代码
import java.util.*;
/*
 * public class TreeNode {
 * int val = 0;
 * TreeNode left = null;
 * TreeNode right = null;
 * public TreeNode(int val) {
 * this.val = val;
 * }
 * }
 */
public class Solution
{
 int ret = -1010;
 public int maxPathSum (TreeNode root) 
 {
 dfs(root);
 return ret;
 }
 int dfs(TreeNode root)
 {
 if(root == null) return 0;
 int l = Math.max(0, dfs(root.left)); // 左⼦树为根的最⼤单链和 int r = Math.max(0, dfs(root.right)); // 右⼦树为根的最⼤单链和 // 经过root的最⼤路径和
 ret = Math.max(ret, root.val + l + r);
 return root.val + Math.max(l, r);
 }
}
相关推荐
轻口味7 分钟前
【HarmonyOS Next NAPI 深度探索1】Node.js 和 CC++ 原生扩展简介
c++·harmonyos·harmonyos next·napi·harmonyos-next
高一学习c++会秃头吗9 分钟前
leetcode_2816. 翻倍以链表形式表示的数字
算法·leetcode·链表
swoole~9 分钟前
Docker Compose 教程
java·docker·eureka
坑里技术员1 小时前
Python标准库之SQLite3
java·开发语言·jvm
mycqyjn1 小时前
Java一个简单的反弹动画练习
java·开发语言
冠位观测者1 小时前
【Leetcode 热题 100】739. 每日温度
数据结构·算法·leetcode
ytuglt1 小时前
android framework.jar 在应用中使用
android·java·jar
爱喝ad奶1 小时前
maven 下载依赖 jhash:2.1.2 和对应 jar 包
java·maven·jar
yanglee02 小时前
L4-Prompt-Delta
人工智能·算法·语言模型·prompt
Yang-Never2 小时前
Shader -> RadialGradient圆心渐变着色器详解
android·java·kotlin·android studio