【SSL 2401】天地一抹红(斜率优化 DP)

天地一抹红

题目链接:SSL 2401

题目大意

有一个 n*m 的网格,要从 (1,1) 走到 (n,m)。
然后你可以花费当前格的代价从 (i,j) 走到 (i+1,j),或者走到 (i,k) 其中 k>j。
当你走到 (i,k) 的时候,你可以选择 (i,j)~(i,k-1) 中地方含有宝石价值的最大值,然后就会给你贡献这个最大值乘 (i,k) 位置的法阵强度。
然后要你最大化最后走到 (n,m) 的贡献,如果无法非负就输出 -1。

思路

那肯定是一行一行的走,那行之间的转移只有一种而且很简单。
就直接 fi,j=max(fi,j,fi1,jwi1,j)

然后考虑列的,那一个 O(m2) 每次的转移就是:
fi,j=max(fi,j,maxk=1j1fi,kwi,k+Vi,k,j1ai,j)
Vi,l,r=maxj=lrvi,j

那注意到特别的就是 ai,jai,j+1
那按这么来说,考虑转移点,fi,kwi,k 越来越重要,Vi,k,j1 越来越不重要,那就其实有一个决策的单调性,可以用斜率优化 DP。
考虑改一下,固定 vi,j,然后前面的 fi,kwi,k 是最大值,这个好处是可以直接顺着枚举过来的时候直接维护,因为维护的事 maxj=1kfi,jwi,j
然后你队列维护单调递减的 V,然后这些地方作为转移点,然后斜率优化就行了。

代码

#include<cstdio> #include<cstring> #include<iostream> #define ll long long using namespace std; const int N = 105; const int M = 20005; int n, m, F, sta[M]; ll w[N][M], h[N][M], a[N][M], f[N][M], g[M]; int re; char c; int read() { re = 0; c = getchar(); while (c < '0' || c > '9') c = getchar(); while (c >= '0' && c <= '9') { re = (re << 3) + (re << 1) + c - '0'; c = getchar(); } return re; } double clac(int i, int x, int y) { return 1.0 * (g[y] - g[x]) / (h[i][x] - h[i][y]); } int main() { freopen("red.in", "r", stdin); freopen("red.out", "w", stdout); n = read(); m = read(); F = read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) w[i][j] = read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) h[i][j] = read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) a[i][j] = read(); memset(f, -0x3f, sizeof(f)); f[0][1] = F; for (int i = 1; i <= n; i++) { f[i][1] = f[i - 1][1] - w[i - 1][1]; g[1] = f[i][1] - w[i][1]; int l = 1, r = 0; sta[++r] = 1; for (int j = 2; j <= m; j++) { while (l < r && clac(i, sta[l], sta[l + 1]) >= a[i][j]) l++; f[i][j] = max(f[i - 1][j] - w[i - 1][j], g[sta[l]] + h[i][sta[l]] * a[i][j]); g[j] = max(g[j - 1], f[i][j] - w[i][j]); while (l <= r && h[i][j] >= h[i][sta[r]]) r--; while (l < r && clac(i, sta[r - 1], j) >= clac(i, sta[r - 1], sta[r])) r--; sta[++r] = j; } } if (f[n][m] >= 0) printf("%lld", f[n][m]); else printf("-1"); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/SSL_2401.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2022-03-31 【luogu P5903】【模板】树上 k 级祖先(长链剖分)
2022-03-31 Stardust的矩阵(分治)
2022-03-31 【ZOJ 1654】Place the Robots(网络流)
点击右上角即可分享
微信分享提示