看文先三连,养成好习惯~看文先三连,养成好习惯~看文先三连,养成好习惯~
目录
动态规划:(Dynamic Programming,简称DP)
知识点:
最优子结构:
一个问题的最优解包含子问题的最优解,那么是最优子结构
动态规划:(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;
}
创作不易,点个关注吧~创作不易,点个关注吧~创作不易,点个关注吧~