17-8-1
题目描述
数字金字塔问题
解答
d[i][j]=max(d[i-1][j],d[i-1][j-1])+x[i][j];
下一行只与上一行求得的最大值有关
有待优化
代码
/*
ID: 18795871
PROG: numtri
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
ifstream fin("numtri.in");
ofstream fout("numtri.out");
const int N = 1000;
int dp[N+1][N+1],x[N+1][N+1];
int n;
int main(){
int i,j;
while (fin>>n){
for (i=1;i<=n;i++){
for (j=1;j<=i;j++){
fin>>x[i][j];
}
}
dp[1][1]=x[1][1];
for (i=2;i<=n;i++){
for (j=1;j<=i;j++){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+x[i][j];
}
}
int res=0;
for (j=1;j<=n;j++){
res=max(res,dp[n][j]);
}
fout<<res<<endl;
}
return 0;
}
这个代码有许多需要优化的地方:
比如说dp数组,其实就只和上一层的状态有关,假设当前我们来到了第i+1层,那么我们只需要知道第i层当前求得的最大值即可,那么我们就可以将它压缩成一维的了,需要注意的是:如果我们j的循环还是从小到大的话,那么我们上一层的j状态已经被上一步操作更新过了,所以我们应该从大到小循环。
/*
ID: 18795871
PROG: numtri
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
ifstream fin("numtri.in");
ofstream fout("numtri.out");
const int N = 1000;
int dp[N+1],x[N+1][N+1];
int n;
int main(){
int i,j;
while (fin>>n){
for (i=1;i<=n;i++){
for (j=1;j<=i;j++){
fin>>x[i][j];
}
}
dp[1]=x[1][1];
for (i=2;i<=n;i++){
for (j=i;j>=1;j--){
dp[j]=max(dp[j],dp[j-1])+x[i][j];
}
}
int res=0;
for (j=1;j<=n;j++){
res=max(res,dp[j]);
}
fout<<res<<endl;
}
return 0;
}
不难发现,我们的x数组也是没有必要存的(以后要用到的才有必要进行存储),于是乎,就有了最简洁的那一种。
/*
ID: 18795871
PROG: numtri
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
ifstream fin("numtri.in");
ofstream fout("numtri.out");
const int N = 1000;
int dp[N+1];
int n;
int main(){
int i,j,t;
while (fin>>n){
int res=0;
for (i=1;i<=n;i++){
for (j=1;j<=i;j++){
fin>>t;
dp[i-j+1]=max(dp[i-j+1],dp[i-j])+t;
res=max(res,dp[i-j+1]);
}
}
fout<<res<<endl;
}
return 0;
}