Interesting Punch-Bowl 搜索+优先队列

Interesting Punch-Bowl

思路

1,水肯定从高往低处流,周围的格子就不用考虑了
2,首先考虑每个点在它所在行和列中能装的最多的水,即:在每行中,它左边最高的点和右边最高的点的最小值是该点在这一行中能装的最多的水,列同理,取行和列的最小值即可。
3,当所有点的在行和列中能取的最大值都能确立后,只需从最小值的点考虑即可。
4,取最小的一个值,则该值肯定是该点最多填的水,该点周围的水位都比它高,故该点的值确立后,周围的点的水的高度即是该点的高度了。更新四周,直到遇到柱子高度比该水位高的点时,不能扩展了,但要把该点的水位最高值改为柱子的高度。
5,这样贪心的扩展直到所有点的水位确定时,此时的答案是最优的。

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define fi first
#define se second
#define pb push_back

#define foa(x, y, z) for(int x = (y), ooo = (z); x <= z; ++x)
#define fos(x, y, z) for(int x = (y), ooo = (z); x >= z; --x)
#define ckmax(x, y) ((x) < (y) ? (x) = (y), 1 : 0)
#define ckmin(x, y) ((x) > (y) ? (x) = (y), 1 : 0)

typedef pair<int, int> pii;
typedef long long ll;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 300 + 10;
int n, m;
int a[N][N], f[N][N], lf[N][N], rf[N][N], uf[N][N], df[N][N], g[N][N];
struct node
{
	int v, x, y;
	bool operator<(const node &a) const
	{
		return v > a.v;
	}
};
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int ans = 0;
priority_queue<node> q;
void dfs(int x, int y, int v)
{
	if(x <= 1 || x >= n || y <= 1 || y >= m) return;
	if(g[x][y] != -1) return;
	if(a[x][y] > v) {
		ckmin(f[x][y], a[x][y]);
		q.push({f[x][y], x, y});
		return;
	}
	g[x][y] = v;
	ans += v - a[x][y];
	foa(i, 0, 3)
		dfs(x + dx[i], y + dy[i], v);
}
void solve()
{
	cin >> m >> n;
	foa(i, 1, n) 
		foa(j, 1, m)
			cin >> a[i][j];
	foa(i, 1, n) {
		lf[i][1] = a[i][1];
		foa(j, 2, m) 
			lf[i][j] = max(a[i][j], lf[i][j - 1]);
		rf[i][m] = a[i][m];
		fos(j, m - 1, 1)
			rf[i][j] = max(a[i][j], rf[i][j + 1]);
	}
	foa(j, 1, m) {
		uf[1][j] = a[1][j];
		foa(i, 2, n)
			uf[i][j] = max(a[i][j], uf[i - 1][j]);
		df[n][j] = a[n][j];
		fos(i, n - 1, 1)
			df[i][j] = max(a[i][j], df[i + 1][j]);
	}
	
	foa(i, 2, n - 1)
		foa(j, 2, m - 1){
			f[i][j] = min({lf[i][j], rf[i][j], uf[i][j], df[i][j]});
			q.push({f[i][j], i, j});
		}
	memset(g, -1, sizeof(g));
	while(q.size()) {
		auto t = q.top();
		q.pop();
		if(g[t.x][t.y] != -1 || f[t.x][t.y] != t.v) continue;
		dfs(t.x, t.y, t.v);
	}	
	cout << ans << endl;
	
//	foa(i, 1, n) {
//		foa(j, 1, m) {
//			printf("%d %d %d %d    ", lf[i][j], rf[i][j], uf[i][j], df[i][j]);
//		}
//		printf("\n");
//	}
//	printf("---\n\n");
//	foa(i, 1, n) {
//		foa(j, 1, m) {
//			printf("%d ", g[i][j]);
//		}
//		printf("\n");
//	}
}
signed main()
{
	// ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    
	solve();
    return 0;
}
posted @   1564269628  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示