动态规划__数字三角形
2018-03-27 10:34
211 查看
写了这么久程序,总是卡在动态规划,这次,准备集中攻克一下
如果我们能够保存已解决的子问题的答案,而在需要时简单查一下,这样我们就可以避免大量的重复计算,从而得到多项式时间的算法。
为了实现上述算法,我们用一个数组来记录所有已解决的子问题的答案,无论子问题以后是否被用到,只要它被计算过,就将其存入数组中,这种方法在程序设计中被称为动态规划。
由浅到难进行攻克,选择【牛客网——数字三角形】作为第一题。同时也是IOI’94年的题网址是:https://www.nowcoder.com/practice/88c6d56d78974869aac605a0d26deded?tpId=3&&tqId=10888&rp=8&ru=/activity/oj&qru=/ta/hackathon/question-ranking 【题目描述】如下所示为一个数字三角形:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
请编一个程序计算从顶到底的某处的一条路径,使该路径所经过的数字的总和最大每一步可沿直线向下或右斜线向下走。1<三角形行数≤100三角形中的数字为整数0,1,。。。,99 【输入描述】输入包含多组。每组数据的第一行包含一个正整数n(1≤n≤100),代表三角形的层数。
紧接着有n行数字,第i(1≤i≤n)行包含i个自然数。 【输出描述】对应每组数据,输出最大的和。 看到了题目要求是会输入多组,哎。。。。怎么输入多组呢?C++解决方法:int n;while (cin >> n){ //执行的方法}JAVA解决方法:Scanner sc=new Scanner(System.in);while(sc.hasNext()) { int n = sc.nextInt(); //执行的方法} 分析:由于某个点只可能走到它的下方或斜下方(如图8向下到2,向斜下到7)。也可以这么看,7只能由8或1到达。73 8
8 1 0↓↘↓
2 7 4 4
4 5 2 6 5因此,最优路径必定与其左上方或正上方两个位置的最优路径有关。(7的最优路径必定于8或1的最优路径有关) 用二维数组a来记录数字三角形中的数,a[ i , j ]表示数字三角形中第i行的第j个数。用二维数组m记录每个位置的最优路径的数字总和。计算数组m用逐行递推的方法实现。 关键公式:m[ i , j ] = a[ i , j ] + max{ m[ i+1 , j ] , m[ i+1 ,j+1]} 例:a[ 2 , 0] = 8 a[ 3 , 0] = 2 a[ 3 , 1 ] = 7m[ 2 , 0] = a[2 , 0 ] + max{ m[ 3 , 0 ] , m[ 3 , 1 ]}
JAVA代码:import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int n;//行数
int[][] a;//存放三角形
int[][] m;//存放运算结果
Scanner sc = new Scanner(System.in);
while(sc.hasNext())
{
n = sc.nextInt();
a = new int
;
m = new int
;
for (int i7=0;i7<n;i7++)
Arrays.fill(m[i7], 0);
for(int i1=0;i1<n;i1++)
{
for(int i2=0;i2<=i1;i2++)
{
a[i1][i2]=sc.nextInt();
}
}
for(int i3=0;i3<n;i3++)
{
m[n-1][i3] = a[n-1][i3];
}
if(n>1)
{
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;j++)
{
if(m[i+1][j]>m[i+1][j+1])
{
m[i][j]=a[i][j]+m[i+1][j];
}
else
{
m[i][j]=a[i][j]+m[i+1][j+1];
}
}
}
}
System.out.println(m[0][0]);
}
}
}
如果我们能够保存已解决的子问题的答案,而在需要时简单查一下,这样我们就可以避免大量的重复计算,从而得到多项式时间的算法。
为了实现上述算法,我们用一个数组来记录所有已解决的子问题的答案,无论子问题以后是否被用到,只要它被计算过,就将其存入数组中,这种方法在程序设计中被称为动态规划。
由浅到难进行攻克,选择【牛客网——数字三角形】作为第一题。同时也是IOI’94年的题网址是:https://www.nowcoder.com/practice/88c6d56d78974869aac605a0d26deded?tpId=3&&tqId=10888&rp=8&ru=/activity/oj&qru=/ta/hackathon/question-ranking 【题目描述】如下所示为一个数字三角形:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
请编一个程序计算从顶到底的某处的一条路径,使该路径所经过的数字的总和最大每一步可沿直线向下或右斜线向下走。1<三角形行数≤100三角形中的数字为整数0,1,。。。,99 【输入描述】输入包含多组。每组数据的第一行包含一个正整数n(1≤n≤100),代表三角形的层数。
紧接着有n行数字,第i(1≤i≤n)行包含i个自然数。 【输出描述】对应每组数据,输出最大的和。 看到了题目要求是会输入多组,哎。。。。怎么输入多组呢?C++解决方法:int n;while (cin >> n){ //执行的方法}JAVA解决方法:Scanner sc=new Scanner(System.in);while(sc.hasNext()) { int n = sc.nextInt(); //执行的方法} 分析:由于某个点只可能走到它的下方或斜下方(如图8向下到2,向斜下到7)。也可以这么看,7只能由8或1到达。73 8
8 1 0↓↘↓
2 7 4 4
4 5 2 6 5因此,最优路径必定与其左上方或正上方两个位置的最优路径有关。(7的最优路径必定于8或1的最优路径有关) 用二维数组a来记录数字三角形中的数,a[ i , j ]表示数字三角形中第i行的第j个数。用二维数组m记录每个位置的最优路径的数字总和。计算数组m用逐行递推的方法实现。 关键公式:m[ i , j ] = a[ i , j ] + max{ m[ i+1 , j ] , m[ i+1 ,j+1]} 例:a[ 2 , 0] = 8 a[ 3 , 0] = 2 a[ 3 , 1 ] = 7m[ 2 , 0] = a[2 , 0 ] + max{ m[ 3 , 0 ] , m[ 3 , 1 ]}
JAVA代码:import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int n;//行数
int[][] a;//存放三角形
int[][] m;//存放运算结果
Scanner sc = new Scanner(System.in);
while(sc.hasNext())
{
n = sc.nextInt();
a = new int
;
m = new int
;
for (int i7=0;i7<n;i7++)
Arrays.fill(m[i7], 0);
for(int i1=0;i1<n;i1++)
{
for(int i2=0;i2<=i1;i2++)
{
a[i1][i2]=sc.nextInt();
}
}
for(int i3=0;i3<n;i3++)
{
m[n-1][i3] = a[n-1][i3];
}
if(n>1)
{
for(int i=n-2;i>=0;i--)
{
for(int j=0;j<=i;j++)
{
if(m[i+1][j]>m[i+1][j+1])
{
m[i][j]=a[i][j]+m[i+1][j];
}
else
{
m[i][j]=a[i][j]+m[i+1][j+1];
}
}
}
}
System.out.println(m[0][0]);
}
}
}
相关文章推荐
- 数字三角形问题 (动态规划初步)
- [动态规划]数字三角形2
- 数字三角形 (动态规划与递归)
- POJ 1163 求数字三角形由顶到底边的最大数字和 动态规划
- hihoCoder 1037 : 数字三角形 动态规划
- 【动态规划】数字三角形问题
- hihoCoder - 1037 - 数字三角形 (动态规划)
- 动态规划之数字三角形问题
- 数字三角形--动态规划
- 洛谷Oj-数字三角形-动态规划
- 动态规划——数字三角形最大和
- POJ1163 The Triangle(数字三角形) (动态规划初步)
- 经典算法题:数字三角形寻找最大路径——动态规划和递归调用两种解法
- poj3176Cow Bowling,数字三角形,动态规划
- POJ_3176_Cow_Bowling_(数字三角形)_(动态规划)
- 数字三角形 动态规划
- 数字三角形(版本I-III)[动态规划]
- |Tyvj|动态规划|P1044 数字三角形
- poj1163 数字三角形 (动态规划)
- poj 1163数字三角形问题--动态规划