您的位置:首页 > 其它

数字三角形_递归_递推(动态规划)

2016-09-14 21:46 411 查看
输入格式:

5 // 三角形行数,下面是三角形

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

三角形的行数大于1小于等于100,数字为 0 – 99。

要求输出最大和,不必给出具体路径。

思路

D(r,j):第r行第j个数字(r,j从1开始算)

MaxSum(r,j):从D(r,j)到底边的各条路径中,最佳路径的数字之和

问题:求MaxSum(1,1)

D(r,j)出发,下一步只能走D(r+1,j)或者D(r+1,j+1)

对于N行的三角形:

if(r == N)
MaxSum(r,j) = D(r,j)
else
MaxSum(r,j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)


递归

#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;

int D[MAX][MAX];
int n;

int MaxSum(int i, int j) {
if(i == n)
return D[i][j];
int x = MaxSum(i+1,j);
int y = MaxSum(i+1,j+1);
return max(x,y) + D[i][j];
}

int main(){
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
cin>>D[i][j];
cout<< MaxSum(1,1) <<endl;
return 0;
}


改进

每算出一个MaxSum(r,j)就保存起来,下次用到其值的时候直接取用,则可免去重复计算。

记忆递归型动态规划

#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;

int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];

int MaxSum(int i, int j) {
if(maxSum[i][j] != -1)
return maxSum[i][j];
if(i == n)
maxSum[i][j] = D[i][j];
else {
int x = MaxSum(i+1,j);
int y = MaxSum(i+1,j+1);
maxSum[i][j] = max(x,y) + D[i][j];
}
return maxSum[i][j];
}

int main() {
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++) {
cin>>D[i][j];
maxSum[i][j] = -1;
}
cout<< MaxSum(1,1) <<endl;
return 0;
}


30
2321
201310
7121010
45265
递推型动态规划

#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;

int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];

int main() {
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
cin>>D[i][j];
for(int i=1; i<=n; i++)
maxSum
[i] = D
[i];
for(int i=n-1; i>=1; i--)
for(int 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;
}


空间优化动态规划

用D的第n行替代maxSum

#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;

int D[MAX][MAX];
int n;
int *maxSum;

int main() {
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
cin>>D[i][j];
maxSum = D
;  // maxSum指向第n行
for(int i=n-1; i>=1; i--)
for(int j=1; j<=i; j++)
maxSum[j] = max(maxSum[j], maxSum[j+1]) + D[i][j];
cout<<maxSum[1]<<endl;
return 0;
}


北大的公开课真心不错,感觉比现在上的算法课好很多(●’◡’●)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息