U301495 432.晴天小猪历险记之Hill 题解

solve

  • 要跑两遍dp
  • 要不然从左右端点转移不过来
  • 注意左下的转移是从j而不是从j+1(可以理解为金字塔但不是金字塔,而是样例给的样子)

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
int dp[maxn][maxn];
int g[maxn][maxn];
int n;
int mymin(int a,int b,int c,int d)
{
	a=min(a,b);
	a=min(a,c);
	a=min(a,d);
	return a;
}
int myminn(int a,int b,int c,int d,int e)
{
	a=min(a,b);
	a=min(a,c);
	a=min(a,d);
	a=min(a,e);
	return a;
}
int main()
{
	cin >> n;
	memset(dp,0x3f,sizeof(dp));
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=i;j++)
		{
			cin >> g[i][j];
		}
	}
	dp[n][1]=g[n][1];
	for (int i=n;i>=1;i--)
	{
		dp[i][1]=min(dp[i][1],dp[i][i]+g[i][1]);
		dp[i][1]=min(dp[i][1],dp[i+1][i+1]+g[i][1]);
		// 对于每行头的转移 
		for (int j=1;j<=i;j++)
		{
			dp[i][j]=min(dp[i][j],dp[i][j-1]+g[i][j]);
			dp[i][j]=min(dp[i][j],min(dp[i+1][j],dp[i+1][j+1])+g[i][j]);
		}
		dp[i][i]=min(dp[i][i],dp[i][1]+g[i][i]);
		dp[i][i]=min(dp[i][i],dp[i+1][1]+g[i][i]);
		// 对于每行尾的转移
		for (int j=i-1;j>=1;j--)
		{
			dp[i][j]=min(dp[i][j],dp[i][j+1]+g[i][j]);
		}
		// 第二次
		dp[i][1]=min(dp[i][1],dp[i][i]+g[i][1]);
		dp[i][1]=min(dp[i][1],dp[i+1][i+1]+g[i][1]);
		for (int j=1;j<=i;j++)
		{
			dp[i][j]=min(dp[i][j],dp[i][j-1]+g[i][j]);
			dp[i][j]=min(dp[i][j],min(dp[i+1][j],dp[i+1][j+1])+g[i][j]);
		}
		dp[i][i]=min(dp[i][i],dp[i][1]+g[i][i]);
		dp[i][i]=min(dp[i][i],dp[i+1][1]+g[i][i]);
	}
	cout << dp[1][1] << endl;
	return 0;
}
posted @ 2026-03-22 09:34  msjing  阅读(25)  评论(0)    收藏  举报