栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

邻接表上的动态规划-连续三数和

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

邻接表上的动态规划-连续三数和


连续三数和
    • 食用指南:
    • 题目描述:
    • 题目分析:
    • 算法模板:
    • 代码实现:
      • 法一:
    • 注意点:

食用指南:

Leetcode专栏开启了,由于博主闭关期末,所以每日只能一题
尽量做到一题多解,先说思路,之后代码实现,会添加必要注释
语法或STL内容会在注意点中点出,新手友好
欢迎关注博主神机百炼专栏,内涵算法基础详细讲解和代码模板

题目描述:
  • 一个数分解为三个数之和,且分解结果中不能出现负数

  • 题目来源:

    道友提问

题目分析:
  • 动态规划:后一个数的分解依靠前一个数的分解结果

    第一个数可以分解为多种组合,
    第二数的分解基于第一个数的后两个分解结果,
    只要存在一种分解结果三个数都不为负,即可继续分解下一个数

  • 输出:每次记录当前结果依赖于上一个数的哪种分解组合

    若有多种只记录一种即可,毕竟若可以合法分解,最终一个数的分解组合必然可以倒推回第一种

    且我们判断可否合法分解时将上个数的所有分解组合都审视过了

算法模板:
  • 基础:静态单链表
  • 每个数分解结果的存储:邻接表/矩阵
  • 结果输出:DFS
代码实现: 法一:
#include 
#include 
using namespace std;
const int N = 100010;
int h[N];
int a[N], b[N], c[N], ne[N];
int idx;
int up[N];	//记录当前节点的来源
void add(int x, int num1, int num2, int num3, int y){
	a[idx] = num1;
	b[idx] = num2;
	c[idx] = num3;
	ne[idx] = h[x];
	up[idx] = y;
	h[x] = idx++;
}
void print(int idx){
	if (up[idx] != -1){
		print(up[idx]);
	}
	if(up[idx] == -1){
		cout<
	memset(h, -1, sizeof(h));
	memset(up, -1, sizeof(up));
	int n = 0;
	cin >>n;
	for(int i=0; i
		int x = 0;
		cin >> x;
		if( i == 0){
			for(int j=0; j<=x; j++){
				for(int k=0; k<=x; k++){
					if (x - j - k >= 0){
						add(i,j,k,x-j-k, -1);
					}
				}
			}
		}else{
			int flag = 0;	//当该层有组成时就置为1 
			for(int j = h[i-1]; j!=-1; j=ne[j]){
				if(x - b[j] - c[j] >= 0){
					add(i, b[j], c[j], x-b[j]-c[j],j);
					flag = 1;
				}
			}
			if (flag == 0)	{
				cout<<"No"< 
注意点: 
  • 输出路径:
    本题的路径只有走到终点时才明确,且当走到终点时不能逆推回起点

    类似这样的单向路径记录,我们最好使用up[]记录每个节点的来源节点,让记录路径不额外耗时

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/965503.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号