树上dp dfs

挖地雷

dfs注意最优解不一定是从1节点开始 所以要枚举每个节点

#include<bits/stdc++.h>

using namespace std;

const int N = 21;
int ans[N];
int res;
int a[N];
int b[N][N];
int n;
int cnt;
int A[N];
int s;

void dfs(int i , int sum)
{
	
    if(sum > res)
    {
        for(int l = 0 ; l <= cnt ; l++) A[l] = ans[l];
        res = sum;
        s = cnt;
    }
    
    for(int t = i + 1 ; t <= n ; t++)
    { 
        if(b[i][t]) 
        {
        	ans[++cnt] = t;
            dfs(t,sum+a[t]);
            cnt--;
        }
    }
    
}

int main()
{
    
    
    scanf("%d",&n);
    
    for(int i = 1 ; i <= n  ; i++)
    {
        scanf("%d",&a[i]);
    }
    
   
     int T = n;
     int m = n-1;
    
    for(int i = 1 ; i <= m ; i++)
    {
        for(int j = i + 1 ; j <= T ; j++)
        {
            cin>>b[i][j];
        }
    }
    
  
    
    for(int i = 1 ; i <= n ; i++)
    {
		ans[cnt] = i;
	    dfs(i,a[i]);
    }
    
   
    for(int i = 0 ; i <= s ; i++) cout<<A[i]<<" ";
    
    cout<<'\n'<<res;
    
    return 0;
}

递推 记录一下每个点的前缀 最后输出最大值的那条路

#include<bits/stdc++.h>

using namespace std;

const int N = 21;
int ans[N];
int a[N];
int b[N][N];
int n,p;
int f[N];
int res;

void print(int x)
{
	if(ans[x] != 0) print(ans[x]);
	
    cout<<x<<" ";
}

int main()
{
    
    scanf("%d",&n);
    
    for(int i = 1 ; i <= n  ; i++)
    {
        scanf("%d",&a[i]);
    }
    
     int m = n-1;
    
    for(int i = 1 ; i <= m ; i++)
    {
        for(int j = i + 1 ; j <= n ; j++)
        {
            cin>>b[i][j];
        }
    }
    
    //f[1] = a[1];
    
    for(int i = 1 ; i <= n ; i++)
	{
		f[i] = a[i];
			
		for(int j = i - 1 ; j >= 0 ; j--)
		{
			
			if(b[j][i])
			{
				if(f[j] + a[i] > f[i])
				{
					f[i] = f[j] + a[i];
					
					ans[i] = j;
				}				
			}
		}
		
		if(f[i] > res)
		{
			res = f[i];
			p = i;
		}
	}
   
    print(p);
    
    cout<<'\n'<<res;
    
    return 0;
}
### Python 中基于树结构的动态规划实现 #### 背景介绍 动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法[^3]。当涉及到树形结构时,通常会采用一种称为 **树形 DP** 的方法来解决问题。这种方法的核心在于利用树节点之间的父子关系以及递推方程,在遍历过程中逐步构建解决方案。 以下是关于如何在 Python 中实现基于树结构的动态规划的具体说明: --- #### 树形 DP 基本原理 1. **定义状态**: 对于每一个节点 `i`,我们可能需要维护一些与其相关的属性值(例如最大路径和、最小覆盖范围等)。这些值可以通过其子节点的状态转移得到。 2. **状态转移方程**: 利用父节点与子节点的关系建立递推公式。常见的场景包括: - 计算从根到叶子的最大/最短路径; - 找出满足某些约束条件的最佳子树配置; 3. **初始化与边界处理**: 需要特别注意叶节点的情况,因为它们没有子节点可以参与状态转移过程。 4. **后序遍历优先**: 由于树形 DP 往往依赖子节点的结果更新父节点的信息,因此推荐使用深度优先搜索 (DFS) 并按照后序顺序访问各个节点。 --- #### 示例代码:二叉树中的最长递增路径 下面是一个经典的例子——给定一棵二叉树,找到其中任意两个结点之间最长的递增路径长度。 ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def longestIncreasingPath(root: TreeNode) -> int: max_len = 0 def dfs(node): nonlocal max_len if not node: return 0 # 初始化当前节点向左、右延伸的最大递增路径长度 left_inc = 0 right_inc = 0 # 左子树探索 if node.left and node.left.val > node.val: left_inc = dfs(node.left) # 右子树探索 if node.right and node.right.val > node.val: right_inc = dfs(node.right) # 更新全局最大值 current_max_path = 1 + max(left_inc, right_inc) max_len = max(max_len, current_max_path) return current_max_path dfs(root) return max_len ``` 上述代码实现了对二叉树中每条递增路径的查找,并记录下最大的一条路径长度。这里采用了 DFS 来逐层深入并返回各分支上的最佳结果[^1]。 --- #### 结合回溯法的应用扩展 尽管动态规划擅长解决计数类或优化目标的问题,但在实际应用中有时也需要借助回溯技术枚举所有可能性后再筛选符合条件者[^2]。两者结合能够更灵活应对不同类型的挑战。 例如对于寻找特定模式匹配的任务来说,先运用回溯穷尽潜在选项集合,再辅以记忆化存储减少冗余运算,则可显著提升效率。 --- #### 总结 综上所述,针对树型数据结构下的动态规划实践主要围绕以下几个方面展开讨论:一是确立清晰的状态表示形式及其相互间联系规律;二是合理安排迭代次序确保逻辑连贯性;三是综合考虑时间空间开销选取合适策略完成最终解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值