请 求 降 黄
查看原帖
请 求 降 黄
750163
_Kenma_楼主2023/8/15 19:38

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;
}
2023/8/15 19:38
加载中...