RT,这个题一眼朴素DP,金字塔路径求最大值也是很典的DP题,(最重要的是十分好写),不具有绿题应有的思维含量和编写难度,而且!赛时像我一样上来没想就直接打暴力的人应该不少。
就像这样(忘了谈论区能不能贴代码了,违规紫衫)
#include<bits/stdc++.h>
using namespace std;
long long n;
long long ans=-1;
long long ansi=2e16+10;
long long f[1005][1005];
long long d[1005][1005];
long long h[1005][1005];
int main(){
cin>>n;
for(long long i=1;i<=n;i++){
for(long long j=1;j<=i;j++){
cin>>h[i][j];
}
}
for(long long i=1;i<=n;i++){
long long maxn=-1;
for(long long j=1;j<=i;j++){
maxn=max(maxn,h[i][j]);
}
for(long long j=1;j<=i;j++){
if(f[i-1][j]>f[i-1][j-1]){
f[i][j]=f[i-1][j];
d[i][j]=d[i-1][j];
}else{
f[i][j]=f[i-1][j-1];
if(f[i-1][j]!=f[i-1][j-1]) d[i][j]=d[i-1][j-1];
else d[i][j]=min(d[i-1][j-1],d[i-1][j]);
}
//f[i][j]=max(f[i-1][j],f[i-1][j-1]);
//d[i][j]=min(d[i-1][j],d[i-1][j-1]);
if(maxn>h[i][j]){
f[i][j]+=maxn;
d[i][j]++;
}else f[i][j]+=h[i][j];
}
}
for(long long i=1;i<=n;i++){
if(ans<f[n][i]){
ans=f[n][i];
ansi=d[n][i];
}else if(ans==f[n][i]) ansi=min(d[n][i],ansi);
}
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
for(long long i=0;i<=n+1;i++){
for(long long j=0;j<=n+1;j++) d[i][j]=n;
}
for(long long k=n-1;k>=0;k--){
long long maxn=-1;
for(long long i=k+1;i<=n;i++){
long long j=i-k;
maxn=max(maxn,h[i][j]);
}
for(long long i=k+1;i<=n;i++){
long long j=i-k;
if(f[i][j-1]>f[i+1][j]){
f[i][j]=f[i][j-1];
d[i][j]=d[i][j-1];
}else{
f[i][j]=f[i+1][j];
if(f[i][j-1]!=f[i+1][j]) d[i][j]=d[i+1][j];
else d[i][j]=min(d[i][j-1],d[i+1][j]);
}
//f[i][j]=max(f[i][j-1],f[i+1][j]);
//d[i][j]=min(d[i][j-1],d[i+1][j]);
if(maxn>h[i][j]){
f[i][j]+=maxn;
d[i][j]++;
}else f[i][j]+=h[i][j];
}
}
for(long long i=1;i<=n;i++){
if(ans<f[i][i]){
ans=f[i][i];
ansi=d[i][i];
}else if(ans==f[i][i]) ansi=min(d[i][i],ansi);
}
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
for(long long i=1;i<=n+1;i++){
for(long long j=1;j<=n+1;j++) d[i][j]=2*n;
}
for(long long j=n;j>=1;j--){
long long maxn=-1;
for(long long i=j;i<=n;i++){
maxn=max(maxn,h[i][j]);
}
for(long long i=j;i<=n;i++){
if(f[i][j+1]>f[i+1][j+1]){
f[i][j]=f[i][j+1];
d[i][j]=d[i][j+1];
}else{
f[i][j]=f[i+1][j+1];
if(f[i][j+1]!=f[i+1][j+1]) d[i][j]=d[i+1][j+1];
else d[i][j]=min(d[i][j+1],d[i+1][j+1]);
}
//f[i][j]=max(f[i][j+1],f[i+1][j+1]);
//d[i][j]=min(d[i][j+1],d[i+1][j+1]);
if(maxn>h[i][j]){
f[i][j]+=maxn;
d[i][j]++;
}else f[i][j]+=h[i][j];
}
}
for(long long i=1;i<=n;i++){
if(ans<f[i][1]){
ans=f[i][1];
ansi=d[i][1];
}else if(ans==f[i][1]) ansi=min(d[i][1],ansi);
}
cout<<ans<<" "<<ansi;
return 0;
}