这题我有闪过是用单调队列优化的想法,也想过有左右两边各烧一遍。 但是不敢确定,搜了题解,发现真的是用单调队列,然后写了好久,调了好久下标应该怎么变化才过的。

dp[i][j] 表示走到第i行,第j个竖线的最大价值。

dp[i][j] = max(dp[i-1][k]+pre[i][j-1]-pre[i][k-1]);  从左往右

dp[i][j] = max(dp[i][j],dp[i-1][k]+suf[i][j]-suf[i][k]); 从右往左

 #pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
const int INF = << ;
typedef __int64 LL;
/*
dp[i][j]表示走到第i个横线,第j个竖线的最大值
dp[i][j] = max(dp[i-1][k] + sum[j-1] - sum[k-1])
单调队列优化维护队首最大值,
*/ int q[], head, tail;
int dp[][];
int a[][];
int b[][];
int pre[][], suf[][];
int sum1[][];
int sum2[][];
int main()
{
int n, m, k; while (scanf("%d%d%d", &n, &m, &k),n+m+k)
{
memset(dp, , sizeof(dp));
memset(pre, , sizeof(pre));
memset(suf, , sizeof(suf));
memset(sum1, , sizeof(sum1));
memset(sum2, , sizeof(sum2));
n++;
for (int i = ;i <= n;++i)
{
for (int j = ;j <= m;++j)
{
scanf("%d", &a[i][j]);
pre[i][j] = pre[i][j - ] + a[i][j];
suf[i][j] = a[i][j];
}
for (int j = m;j >= ;--j)
suf[i][j] += suf[i][j + ]; }
for (int i = ;i <= n;++i)
{
for (int j = ;j <= m;++j)
{
scanf("%d", &b[i][j]);
sum1[i][j] = b[i][j];
sum2[i][j] = sum2[i][j - ] + b[i][j];
}
for (int j = m;j >= ;--j)
sum1[i][j] += sum1[i][j + ];
}
for (int i = n;i >= ;--i)
{
head = tail = ;
for (int j = ;j <= m + ;++j)
{
while (head < tail && dp[i + ][j] - pre[i][j - ] >= dp[i + ][q[tail - ]] - pre[i][q[tail - ] - ])
tail--;
q[tail++] = j;
while (head<tail && sum2[i][j-] - sum2[i][q[head]-]>k)
head++;
dp[i][j] = dp[i + ][q[head]] + pre[i][j - ] - pre[i][q[head]-];
}
head = tail = ; for (int j = m+;j >= ;--j)
{
while (head < tail&&dp[i + ][j] - suf[i][j ] >= dp[i + ][q[tail - ]] - suf[i][q[tail - ] ])
tail--;
q[tail++] = j;
while (head<tail&&sum1[i][j] - sum1[i][q[head]]>k)
head++;
dp[i][j] =std::max(dp[i][j], dp[i + ][q[head]] + suf[i][j] - suf[i][q[head]]);
}
}
int ans = ;
for (int j = ;j <= m + ;++j)
ans = std::max(ans, dp[][j]);
printf("%d\n", ans);
}
return ;
}

uvalive4327(单调队列优化)的更多相关文章

  1. BestCoder Round #89 02单调队列优化dp

    1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01  HDU 5944   水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...

  2. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  3. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  4. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  5. UESTC 880 生日礼物 --单调队列优化DP

    定义dp[i][j]表示第i天手中有j股股票时,获得的最多钱数. 转移方程有: 1.当天不买也不卖: dp[i][j]=dp[i-1][j]; 2.当天买了j-k股: dp[i][j]=max(dp[ ...

  6. poj 1821 Fence 单调队列优化dp

    /* poj 1821 n*n*m 暴力*/ #include<iostream> #include<cstdio> #include<cstring> #incl ...

  7. 使用单调队列优化的 O(nm) 多重背包算法

    我搜索了一下,找到了一篇很好的博客,讲的挺详细:链接. 解析 多重背包的最原始的状态转移方程: 令 c[i] = min(num[i], j / v[i]) f[i][j] = max(f[i-1][ ...

  8. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  9. 1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)

    这道题吗= =首先解决了我多年以来对仙人掌图的疑问,原来这种高大上的东西原来是这个啊= = 然后,看到这种题,首先必须的就是缩点= = 缩点完之后呢,变成在树上找最长路了= =直接树形dp了 那么那些 ...

随机推荐

  1. Android broadcast

    发送广播而且接受.发送两个广播 Intent intent = new Intent(); intent.setAction("com.wxq.CUSTOM_INTENT"); s ...

  2. Codeforces Round #218 (Div. 2)

    500pt, 题目链接:http://codeforces.com/problemset/problem/371/A 分析:k-periodic说明每一段长度为k,整个数组被分成这样长度为k的片段,要 ...

  3. android中,如果使用imageButton可以在drawable 中设置一个selector,但是imageView设置不起作用

    android中,如果使用imageButton可以在drawable 中设置一个selector,但是imageView设置不起作用,只要把Imageview的src给去掉就成了,src捕获了bac ...

  4. 【老鸟学算法】包含 min函数的栈设计——java实现

    要求: 1. 定义栈的数据结构,要求添加一个 min函数,能够得到栈的最小元素. 2. 要求函数 min.push 以及 pop 的时间复杂度都是 O(1). 这是考验“栈”数据结构设计.众所周知,栈 ...

  5. [Java][Android][Process] ProcessBuilder与Runtime差别

    在Android中想要进行Ping,在不Root机器的情况下似乎还仅仅能进行底层命调用才干实现. 由于在Java中要进行ICMP包发送须要Root权限. 于是仅仅能通过创建进程来攻克了.创建进程在Ja ...

  6. Windbg抓取程序崩溃的dmp文件的方法

    Windbg抓取程序崩溃的dmp文件的方法 一.        简介 windbg是在windows平台下,强大的用户态和内核态调试工具.相比较于Visual Studio,它是一个轻量级的调试工具, ...

  7. java反射机制 + Method.invoke解释 getMethod + 反射理解

    功能: 通过读取另一个Dll去创建一个控件(Form,Button,TextBox,DataGridView),然后对当中一些属性进行检查. 创建控件的大致流程是,Assembly->Modul ...

  8. [置顶] android开发之来电自动拒接并自动回复短信_上课模式app

    上课的时候老师说总是错过电话,对方打来没人接还一遍遍的打,觉得可以有个app在上课期间自动拒接电话,并自动回复短信过去. 当然了,需要权限的. 尝试做了个雏形出来. 界面如下: 主要代码如下: pac ...

  9. java学习笔记05--字符串 .

    java学习笔记05--字符串 . 一.String类 由字符所组成的一串文字符号被称之为字符串.在java中字符串不仅仅是字符数组,而且是String类的一个实例,可以使用String类来构建. 字 ...

  10. MVC Json 回报

    /// <summary> /// 获取评论列表 /// </summary> /// <param name="pageIndex">< ...