递归和动态规划,但是~
题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
在上面的样例中,从 7→3→8→7→5 的路径产生了最大权值。
输入格式
第一个行一个正整数 r ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
输入输出样例
输入 #1复制
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5输出 #1复制
30说明/提示
【数据范围】
对于 100% 的数据,1≤r≤1000,所有输入在 [0,100] 范围内。题目翻译来自NOCOW。
首先递归代码,当然都是不完全过的,都TLE
//普通递归写法
#include<bits/stdc++.h>
using namespace std;
int t=-1;
int r;
int sum[1100][1100]={0};
int arr[1100][1100]={0};
int dp[1100][1100]={0};
void dfs(int x,int y,int sum){
if(y<=x){
if(x>r){
t=max(t,sum);
return ;
}
dfs(x+1,y,sum+arr[x][y]);
dfs(x+1,y+1,sum+arr[x][y]);
}
}
int main()
{
cin>>r;
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
cin>>arr[i][j];
}
}
// sum[1][1]=arr[1][1];
dfs(1,1,0);
cout<<t;
return 0;
}
//记忆化搜索
#include<bits/stdc++.h>
using namespace std;
int t=-1;
int r;
int arr[1100][1100]={0};
int dp[1100][1100]={0};
int dfs(int x,int y){
if(y<=x){
if(x>r){
return dp[x][y];
}
if(dp[x][y]!=0){
return dp[x][y];
}
dp[x][y]=max(dfs(x+1,y),dfs(x+1,y+1))+arr[x][y];
}
return dp[x][y];
}
int main()
{
cin>>r;
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
cin>>arr[i][j];
}
}
t=dfs(1,1);
cout<<t;
return 0;
}
然后是动态规划
#include<bits/stdc++.h>
using namespace std;
int t=-1;
int r;
int arr[1100][1100]={0};
int dp[1100][1100]={0};
int main()
{
cin>>r;
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
cin>>arr[i][j];
}
}
dp[1][1]=arr[1][1];
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
dp[i][j]=max(dp[i-1][j]+arr[i][j],dp[i-1][j-1]+arr[i][j]);
t=max(t,dp[i][j]);
}
}
// for(int i=1;i<=r;i++){
// for(int j=1;j<=i;j++){
// cout<<dp[i][j]<<" ";
// }
// cout<<endl;
// }
cout<<t;
return 0;
}
完结