数字三角形
数字三角形
给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求出一条路径,使路径上的数字的和最大。
代码语言:javascript代码运行次数:0运行复制 7
8
8 1 0
2 7 4 4
4 5 2 6 5
输入格式 第一行包含整数 n,表示数字三角形的层数。
接下来 n 行,每行包含若干整数,其中第 i 行表示数字三角形第 i 层包含的整数。
输出格式 输出一个整数,表示最大的路径数字和。
数据范围 1≤n≤500, −10000≤三角形中的整数≤10000 输入样例: 5 7 8 8 1 0 2 7 4 4 4 5 2 6 5 输出样例: 0
思路
状态表示:f(i,j)
- 集合:从
(i,j)
到最后一层的所有方案 - 属性:
Max
状态计算
- 这条路径可以从
(i+1,j)
走上来,即f(i+1,j)+ai
- 也可以从
(i+1,j+1)
走上来,即f(i+1,j)+ai,j
- 所以状态转移方程就是
f(i,j)=max{fi+1,j,fi+1,j+1}+ai
答案:
- 根据定义,答案就是
f(1,1)
提交代码
c++版本
代码语言:javascript代码运行次数:0运行复制#include<iostream>
using namespace std;
ct int = 1010;
int f[][];
int n;
int main()
{
cin >> n;
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= i; ++ j)
{
scanf("%d", &f[i][j]);
}
}
for (int i = n - 1; i >= 1; -- i)
{
for (int j = n - 1; j >= 1; -- j) // for (int j = 1; j <= i; ++ j) 也可以 但是要慢一些
{
f[i][j] += max(f[i + 1][j + 1], f[i + 1][j]);
}
}
cout << f[1][1];
return 0;
}
思路: 这道题我认为最容易错的点就是边界问题,并且如果是JAVA,容易有溢出问题。
一般就是就是向下走,和向上爬两种思路,向上爬的思路可以不需要考虑边界问题。
而当向下走的时候,需要考虑边界问题。也就是对于f[2][1]的时候,f[1]f[0]并没有设置这个值,默认为0,题中的数字有负数,则会出现错误的最大值。需要对于f进行重置,置为Integer.MI_VALUE.
JAVA中最最容易错的点 :如果f[i][j]= (f[i - 1][j - 1] + a[i][j], f[i - 1][j] + a[i][j])其中的f[i - 1][j - 1]如果为Integer.MI_VALUE,并且a[i][j] = 负数时候,会溢出!!!需要写成 (f[i - 1][j - 1] + f[i - 1][j]);
Java版本
代码语言:javascript代码运行次数:0运行复制import java.util.Scanner;
public class Main {
public static void main (String[] args) {
int[][] a = new int[510][510];
int[][] f = new int[510][510];
Scanner sc = new Scanner(System.in);
int n = ();
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= i; j++) {
a[i][j] = ();
}
}
for (int i = n; i >= 1; i--) {
//从最后一排开始走,从下往上。
for (int j = 1; j <= i; j++) {
f[i][j] = (f[i + 1][j + 1], f[i + 1][j]) + a[i][j];
}
}
println(f[1][1]);
}
}
思路: 状态表示:dp[i][j]dp[i][j]表示到ijij的数值最大值; 状态计算:dp[i][j]=v[i][j]+max(dp[i−1][j−1],dp[i−1][j])
Python版本
代码语言:javascript代码运行次数:0运行复制n = int(input())
v = [[0 for _ in range(n + 1)] for _ in range(n + 1)]
for i in range(1, n + 1):
in_ = list(map(int, input().split()))
v[i][1:len(in_) + 1] = in_
IF = 10001
dp = [[-IF for _ in range(n + 1)] for _ in range(n + 1)]
dp[1][1] = v[1][1]
for i in range(2, n + 1):
for j in range(1, i + 1):
dp[i][j] = v[i][j] + max(dp[i - 1][j - 1], dp[i - 1][j])
print(max(dp[n][1:]))
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:202-01-1,如有侵权请联系 cloudcommunity@tencent 删除dpintmax集合数据 #感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
下一篇:连通块中点的数量
推荐阅读
留言与评论(共有 16 条评论) |
本站网友 太仓南洋影院 | 20分钟前 发表 |
fi+1 | |
本站网友 章涛 | 19分钟前 发表 |
−10000≤三角形中的整数≤10000 输入样例: 5 7 8 8 1 0 2 7 4 4 4 5 2 6 5 输出样例: 0思路 状态表示:f(i | |
本站网友 抢票利器 | 10分钟前 发表 |
len(in_) + 1] = in_ IF = 10001 dp = [[-IF for _ in range(n + 1)] for _ in range(n + 1)] dp[1][1] = v[1][1] for i in range(2 | |
本站网友 女性买房猛增 | 11分钟前 发表 |
表示数字三角形的层数 | |
本站网友 吉林敖东洮南药业股份有限公司 | 8分钟前 发表 |
j)+ai也可以从(i+1 | |
本站网友 四川国际标榜职业学院 | 24分钟前 发表 |
j+1)走上来 | |
本站网友 聚尚网 | 13分钟前 发表 |
1)提交代码c++版本代码语言:javascript代码运行次数:0运行复制#include<iostream> using namespace std; ct int = 1010; int f[][]; int n; int main() { cin >> n; for (int i = 1; i <= n; ++ i) { for (int j = 1; j <= i; ++ j) { scanf("%d" | |
本站网友 同仁堂乌鸡白凤丸 | 28分钟前 发表 |
j+1)走上来 | |
本站网友 g7390 | 13分钟前 发表 |
]))本文参与 腾讯云自媒体同步曝光计划 | |
本站网友 闪电部队在前进 | 6分钟前 发表 |
置为Integer.MI_VALUE.JAVA中最最容易错的点 :如果f[i][j]= (f[i - 1][j - 1] + a[i][j] | |
本站网友 童泰官方网站 | 15分钟前 发表 |
f[i - 1][j] + a[i][j])其中的f[i - 1][j - 1]如果为Integer.MI_VALUE | |
本站网友 中铁山语城 | 3分钟前 发表 |
代码语言:javascript代码运行次数:0运行复制 7 8 8 1 0 2 7 4 4 4 5 2 6 5输入格式 第一行包含整数 n | |
本站网友 藿香正气丸说明书 | 12分钟前 发表 |
需要对于f进行重置 | |
本站网友 装修隔断效果图 | 12分钟前 发表 |
使路径上的数字的和最大 | |
本站网友 林州市肿瘤医院 | 0秒前 发表 |
f[i + 1][j]) + a[i][j]; } } println(f[1][1]); } }思路: 状态表示:dp[i][j]dp[i][j]表示到ijij的数值最大值; 状态计算:dp[i][j]=v[i][j]+max(dp[i−1][j−1] |