Poj1163 数字三角形问题 动态规划 记忆性规划

基础的动态规划问题

懂得如何递归加上记忆便轻松解决

代码如下:

#include <iostream> 
using namespace std; 
int Road(int i,int j); 
int Max(int a,int b); 
int n; 
int D[105][105];
int dp[105][105]; 
int main() 
{
   int i,j;
   cin>>n; 
   for(i=1;i<=n;i++)
   for(j=1;j<=i;j++)
   {
      cin>>D[i][j];
      dp[i][j]=-1;
   }
   cout<<Road(1,1)<<endl; 
   return 0;
 } 
 int Road(int i,int j) 
 {
    if(dp[i][j]!=-1) return dp[i][j]; 
    if(i==n) return D[i][j]; 
    return dp[i][j]=Max(Road(i+1,j),Road(i+1,j+1))+D[i][j]; 
 }
 int Max(int a,int b) 
 {
   if(a>b) return a;
   else return b;
}
}

但是,就这样结束了吗?

记忆性递归归根到底还是递归的方法,不可避免的问题就是递归次数过度导致栈溢出。

那么如何解决这个问题?很简单,有递归转化为递推。

从最低层往上推

 

首先需要计算的是最后一行,因此可以把最后一行直接写出,现在开始分析倒数第二行的每一个数,现分析数字2,2可以和最后一行4相加,也可以和最后一行的5相加,但是很显然和5相加要更大一点,结果为7,我们此时就可以将7保存起来,然后分析数字7,7可以和最后一行的5相加,也可以和最后一行的2相加,很显然和5相加更大,结果为12,因此我们将12保存起来。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
int D[105][105];
int maxSum[105][105];
int main()
{
  int i,j,n;
  cin>>n;
  for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
      cin>>D[i][j];
  for(i=1;i<=n;i++)
    maxSum[n][i]=D[n][i];
  for(i=n-1;i>=1;i--)
    for(j=1;j<=i;j++)
      maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];
  cout<<maxSum[1][1]<<endl;
  return 0;
}

显然简单了许多。

 

猜你喜欢

转载自blog.csdn.net/hzaukotete/article/details/79658606