蓝桥杯原题AcWing 3304. 【数字三角形】多种解法:二维dp、三维dp、dfs

文章介绍了使用三维动态规划(三维dp)和二维dp方法解决一个涉及三角形路径问题的C++代码,以及使用dfs进行递归求解的过程。主要关注如何计算从三角形顶点到达边界的不同路径的最优值。
摘要由CSDN通过智能技术生成

用的y总的dp分析法,题解已发布到acwing上,在CSDN记录一下

三维dp:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 110;
int num[N][N], dp[N][N][N];

int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			cin >> num[i][j];
		}
	}
	
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			for(int k = 0; k <= i - 1; k++){
				
				dp[i][j][k] = dp[i - 1][j][k] + num[i][j];
				if(k >= 1){
					dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - 1][k - 1]) + num[i][j];
				} 
			}
		}
	}
	
	int res = 0;
	if(n % 2 == 0){//此时 k = n - 1是奇数会有两种答案 
		//向右走(n - 1) / 2步或者向右走(n - 1) / 2 + 1步数 
		for(int i = 1; i <= n; i++){
			res = max(res, dp[n][i][(n - 1) / 2]);
		}
		for(int i = 1; i <= n; i++){
			res = max(res, dp[n][i][(n - 1) / 2 + 1]);
		}
	}
	else{//此时 k = n - 1是偶数数只有一种答案 
		//向右走(n - 1) / 2步 
		for(int i = 1; i <= n; i++){
			res = max(res, dp[n][i][(n - 1) / 2]);
		}
	}
	
	cout << res << endl;
	return 0;
} 

二维dp:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 110;
int num[N][N], dp[N][N];

int main(){
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			cin >> num[i][j];
		}
	}
	
	
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			if(dp[i - 1][j] >= dp[i - 1][j - 1]){ 
				dp[i][j] = dp[i - 1][j] + num[i][j];//选下边,相当于三角形下一层左边 
			}
			else{
				dp[i][j] = dp[i - 1][j - 1] + num[i][j];//选右下边,相当于三角形下一层右边 
			}
		}
	}
	
	int k = n / 2;
	int p = k + 1;
	if(n % 2 == 0){

		cout << max(dp[n][k], dp[n][p]) << endl;
	}
	else{
		cout << dp[n][p] << endl;
	}
	return 0;
} 

dfs:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 110;
int num[N][N], n, res;

void dfs(int x, int y, int z, int s){//x,y表示当前坐标;z表示当前位移量,向右为正,向左为负;s表示当前总和 
	if(x == n){
		if(z == 0 || z == 1 || z == -1){
			res = max(res, s);
		}
		cout << res << endl;
		return;
	}
	
	dfs(x + 1, y, z - 1, s + num[x + 1][y]);//向下走,相当于三角形中向左走 
	
	dfs(x + 1, y + 1, z + 1, s + num[x + 1][y + 1]);//向右下走,相当于三角形中向右走 
	
}

int main(){
	cin >> n;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= i; j++){
			cin >> num[i][j];
		}
	}
	
	dfs(1, 1, 0, num[1][1]);
	
	cout << res << endl;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值