bzoj 1855 dp + 单调队列优化
Posted cjlhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1855 dp + 单调队列优化相关的知识,希望对你有一定的参考价值。
思路:很容易写出dp方程,很容易看出能用单调队列优化。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 2000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 10000; int n, m, w, ap[N], bp[N], as[N], bs[N], dp[N][N]; int stk[N], head, rear; int cal1(int p, int i, int x) { return dp[p][x] + x * ap[i]; } int cal2(int p, int i, int x) { return dp[p][x] + x * bp[i]; } int main() { scanf("%d%d%d", &n, &m, &w); for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &ap[i], &bp[i], &as[i], &bs[i]); for(int i = 0; i <= n; i++) for(int j = 0; j <= m; j++) dp[i][j] = -inf; dp[0][0] = 0; int ans = 0; for(int i = 1; i <= n; i++) { head = 1, rear = 0; int p = max(0, i - w - 1); for(int j = 0; j <= m; j++) dp[i][j] = dp[i - 1][j]; for(int j = 0; j <= m; j++) { while(rear >= head && cal1(p, i, j) > cal1(p, i, stk[rear])) rear--; stk[++rear] = j; while(j - as[i] > stk[head]) head++; dp[i][j] = max(dp[i][j], cal1(p, i, stk[head]) - j * ap[i]); } head = 1, rear = 0; for(int j = m; j >= 0; j--) { while(rear >= head && cal2(p, i, j) > cal2(p, i, stk[rear])) rear--; stk[++rear] = j; while(j + bs[i] < stk[head]) head++; dp[i][j] = max(dp[i][j], cal2(p, i, stk[head]) - j * bp[i]); ans = max(ans, dp[i][j]); } } printf("%d ", ans); return 0; } /* */
以上是关于bzoj 1855 dp + 单调队列优化的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1855 [Scoi2010]股票交易 单调队列优化dp
笔记篇单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易
BZOJ1855[Scoi2010]股票交易 DP+单调队列