蓝桥杯——说好的进阶之数字三角形

13
11 8
12 7 26
 6 14 15 8
12 7 13 24 11

上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路

径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求

出最佳路径上的数字之和。(每一步可沿直线向下或右斜线向下走,例如,13,8,26,15,24)

/*
输入:
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11

*/
	static int[][] iarr;
	static int[][] p;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		iarr = new int[5][5];
		Scanner scanner = new Scanner(System.in);
		String string="";
		int i=0;
		for(int k=0;k<5;k++)
		{
			string=scanner.nextLine();
			String[] sarr=string.split(" ");
			for(int j=0;j<sarr.length;j++)
			{
				iarr[i][j] = Integer.parseInt(sarr[j]);
			}
			i++;
		}
				
		cal();		
		
	}
	
	static void cal()
	{
		int[][] v = new int[iarr.length][iarr[0].length];
		p = new int[iarr.length][iarr[0].length];
		v[0][0]=iarr[0][0];
		for(int i=1;i<iarr.length;i++)
		{
			for(int j=0;j<iarr[0].length;j++)
			{
				if(j==0)
				{
					v[i][j] = v[i-1][j]+iarr[i][j];
					p[i][j]=1;
				}
				else if(v[i-1][j]>v[i-1][j-1]) {
					v[i][j]=v[i-1][j]+iarr[i][j];
					p[i][j]=1;
				}else if(v[i-1][j-1]>v[i-1][j]) {
					v[i][j]=v[i-1][j-1]+iarr[i][j];
					p[i][j]=2;
				}
			}
		}
		
		for(int[] i:v)
		{
			for(int j:i)
			{
				System.out.printf("%2d ",j);
			}
			System.out.println();
		}
		
		int max=0;
		int n=0;
		for(int j=0;j<iarr[0].length;j++)
		{
			if(max<v[iarr.length-1][j])
			{
				max=v[iarr.length-1][j];
				n=j;
			}
		}
		System.out.println("最佳路径和:"+max);
		System.out.print("最佳路径:");
		get(iarr.length-1, n);
		System.out.print(iarr[iarr.length-1][n]);
	}
	
	static void get(int i,int j)
	{
		if(i==0)
		{
			return;
		}
		if(p[i][j]==1)
		{
			get(i-1, j);
			System.out.print(iarr[i-1][j]+" ");
		}
		if(p[i][j]==2)
		{
			get(i-1, j-1);
			System.out.print(iarr[i-1][j-1]+" ");
		}
	}

### 关于C++实现蓝桥杯数字三角形问题 #### 解题思路 对于数字三角形问题,可以采用动态规划方法来解决。该方法的核心在于自底向上求解最大路径和。具体来说: - 创建一个二维数组 `dp` 来存储到达每个位置的最大路径和。 - 初始化最后一行的数据等于输入数据的最后一行。 - 对于其他每一行,从倒数第二行开始向前遍历,更新每一个节点的最优解为它下方两个子节点较大者加当前节点值。 这种方法能够有效减少重复计算,并且时间复杂度为O(n^2),其中n代表层数[^5]。 #### 代码实现 以下是具体的C++代码实现方式: ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; // 输入三角形高度 vector<vector<int>> triangle(n, vector<int>(n)); // 构建数字三角形矩阵 for(int i = 0; i < n; ++i){ for(int j = 0; j <= i; ++j){ cin >> triangle[i][j]; } } // 动态规划表初始化并填充 vector<vector<int>> dp(triangle); // 自底部向顶部迭代处理 for (int layer = n - 2; layer >= 0; --layer) { for (int pos = 0; pos <= layer; ++pos) { dp[layer][pos] += max(dp[layer + 1][pos], dp[layer + 1][pos + 1]); } } cout << "The maximum sum is: " << dp[0][0]; return 0; } ``` 此程序首先读取用户输入构建起始状态下的数字金字塔;接着创建同样大小的记忆化表格用于记录中间结果;最后按照上述策略完成整个过程直至找到根部到叶子结点之间最大的累加数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值