D4--数字三角形


看文先三连,养成好习惯~看文先三连,养成好习惯~看文先三连,养成好习惯~


目录

知识点:

最优子结构:

动态规划:(Dynamic Programming,简称DP)

基本步骤:

数字三角形:

递推公式:(基础)

~题题题题~

数字三角形:

题目描述

输入描述

输出描述

样例输入

样例输出

代码:

最低通行费

题目描述

输入描述

输出描述

样例输入

样例输出

提示

代码

数字三角形2

题目描述

输入描述

输出描述

样例输入

样例输出

 代码

数字三角形3

题目描述

输入描述

输出描述

样例输入

样例输出

提示

代码:

数字三角形4

题目描述

输入描述

输出描述

样例输入

样例输出

提示

代码


知识点:

最优子结构:

一个问题的最优解包含子问题的最优解,那么是最优子结构

动态规划:(Dynamic Programming,简称DP)

基本步骤:

1、判断问题是否是最优子结构

2、把问题分成若干个子问题

3、建立状态转移方程(递推公式)

4、找出边界条件

5、将已知边界值带入方程

6、递推求解

数字三角形:

递推公式:(基础)

f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];

(f数组是状态数组,a是原数组)

~题题题题~

数字三角形:

题目描述

请编一个程序根据展示出的三角形,计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。

每一步可沿左斜线向下或右斜线向下走;

三角形行数小于等于100;

三角形中的数字为整数;

输入描述

第一行为N,表示有N行 

后面N行表示三角形每条路的路径权,每个路径权不超过10^5大小。

输出描述

路径所经过的数字的总和最大的答案

样例输入

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

样例输出

30

代码:

#include<iostream>
using namespace std;
int a[105][105],n;
long long f[105][105],maxx;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			cin>>a[i][j];
		}
	}
	f[1][1]=a[1][1];
	for(int i=2;i<=n;i++){
		for(int j=1;j<=i;j++){
			f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		maxx=max(f[n][i],maxx);
	}
	cout<<maxx;
	return 0;
}

最低通行费

题目描述

一个商人穿过一个 N*N 的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-2)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。 

这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用? 

注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。 

输入第一行是一个整数,表示正方形的宽度N (1 <= N < 100); 后面 N 行,每行 N 个不大于 100 的整数,为网格上每个小方格的费用。输出至少需要的费用。

输入描述

第一行是一个整数,表示正方形的宽度N (1 <= N < 100);

后面 N 行,每行 N 个不大于 100 的整数,为网格上每个小方格的费用。

输出描述

至少需要的费用。

样例输入

5
1 4 6 8 10 
2 5 7 15 17 
6 8 9 18 20 
10 11 12 19 21 
20 23 25 29 33 

样例输出

109

提示

样例中,最小值为109=1+2+5+7+9+12+19+21+33。

代码

#include<iostream>
#include<cstring>
using namespace std;
int n;
int a[105][105],f[105][105];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		}
	}
	f[1][1]=a[1][1];
	for(int i=1;i<=n;i++){
		f[i][1]=f[i-1][1]+a[i][1];
		f[1][i]=f[1][i-1]+a[1][i];
	}
	for(int i=2;i<=n;i++){
		for(int j=2;j<=n;j++){
			f[i][j]=min(f[i-1][j],f[i][j-1])+a[i][j];
		}
	}
	cout<<f[n][n];
	return 0;
}

数字三角形2

题目描述

数字三角形 要求走到最后mod  100最大

输入描述

第1行n,表示n行  < =25 第2到n+1行为每个的权值

输出描述

mod  100最大值

样例输入

2
1
99 98

样例输出

99

 代码

#include<iostream>
using namespace std;
int a[30][30],n;
long long f[30][30][100],maxx;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			cin>>a[i][j];
		}
	}
	f[1][1][a[1][1]%100]=1;
	for(int i=2;i<=n;i++){
		for(int j=1;j<=i;j++){
			for(int k=0;k<=99;k++){
				if(f[i-1][j][k]==1||f[i-1][j-1][k]==1){
					f[i][j][(k+a[i][j])%100]=1;
				}	
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(long long k=0;k<=99;k++){
			if(f[n][i][k]==1){
				maxx=max(maxx,k);
			}
		}
	}
	cout<<maxx;
	return 0;
}

数字三角形3

题目描述

数字三角形必须经过某一个点,使之走的路程和最大

输入描述

第1行n,表示n行 < =25 第2到n+1行为每个的权值 程序必须经过n / 2,n / 2这个点

输出描述

最大值

样例输入

2
1
1 1

样例输出

2

提示

各个测试点1s

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
long long n,a[105][105],f[105][105];
long long minn=0x3f3f3f3f3f3f3f3f;
int main() {
	cin>>n;
	for(int i=1;i<=n;i++){
	    for(int j=1;j<=i;j++){
	        cin>>a[i][j];
	    }
	}
	f[1][1]=a[1][1];
	int k=n/2;
	a[k][k]+=minn;
	for(int i=2;i<=n;i++){
	    for(int j=1;j<=i;j++){
	        f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];
	    }
	}
	long long maxx=0;
	for(int i=1;i<=n;i++){
	    maxx=max(maxx,f[n][i]);
	}
	cout<<maxx-minn;
	return 0;
}

数字三角形4

题目描述

数字三角形必须经过某一个点,使之走的路程和最大

输入描述

第1行n,表示n行(n< =25)。 第2到n+1行为每个的权值 第n+2行为两个数x,y表示必须经过的点

输出描述

最大值

样例输入

2
1
1 1
1 1

样例输出

2

提示

各个测试点1s

代码

#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
long long n,a[105][105],f[105][105],x,y;
long long minn=0x3f3f3f3f3f3f3f3f;
int main() {
	cin>>n;
	for(int i=1;i<=n;i++){
	    for(int j=1;j<=i;j++){
	        cin>>a[i][j];
	    }
	}
	cin>>x>>y; 
	a[x][y]+=minn;
	f[1][1]=a[1][1];
	for(int i=2;i<=n;i++){
	    for(int j=1;j<=i;j++){
	        f[i][j]=max(f[i-1][j],f[i-1][j-1])+a[i][j];
	    }
	}
	long long maxx=0;
	for(int i=1;i<=n;i++){
	    maxx=max(maxx,f[n][i]);
	}
	cout<<maxx-minn;
	return 0;
}

创作不易,点个关注吧~创作不易,点个关注吧~创作不易,点个关注吧~ 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值