觉得我的解法好简单,好优美啊QAQ

  首先想想暴力怎么办。暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值。这样的复杂度是 \(O(n ^{2} m)\) 的。但是这样明显能够感觉到我们重复计算了很多东西,因为区间 \((l, r)\) 的答案与区间 \((l + 1, r)\) 的答案并不是独立的。

  我们可以考虑一下扫描线的做法。用一根扫描线从右往左扫左端点,同步维护所有以 \(l\) 为左端点的区间。由于我们现已经求出了所有以 \(l + 1\) 为左端点的区间答案(这里的答案指从 \(l -> r\) 中吃东西所能获得的最大权值),我们可以求出 \(l + 1, r\) 到 \(l, r\) 的增量变化,那么 \(ans[l][r] = ans[l + 1][r] + t\)。

  这个答案的增量显然只与 \(l\) 端点所能获得的权值有关。考虑第 j 个购物券,我们可以维护一个值单调递增的单调栈表示在每一个地点使用 j 购物券能获得最大权值的区间。弹栈的时候,我们用 \(val[i][j] - S[j][top].num\) 即可求出增量。这个增量会增加在 \(ans[i][j] -> ans[i][k]\) 这样的一个区间中。差分就可以解决了。

  感觉自己讲起来好混乱啊……すみません……

#include <bits/stdc++.h>
using namespace std;
#define maxn 5005
#define int long long
#define maxm 250
int n, m, dis[maxn], val[maxn][maxm];
int Ans, ans[maxn][maxn], Q[maxn]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct node
{
int num, id;
node(int _id = , int _num = ) { num = _num, id = _id; }
}S[maxm][maxn]; signed main()
{
n = read(), m = read();
for(int i = ; i <= n; i ++) dis[i] = read() + dis[i - ];
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++) val[i][j] = read();
for(int i = ; i <= m; i ++) S[i][].id = n + ;
for(int i = n; i >= ; i --)
{
for(int j = ; j <= m; j ++)
{
int top = Q[j];
ans[i][i] += val[i][j]; ans[i][i + ] -= val[i][j];
while(top && S[j][top].num <= val[i][j])
{
int l = S[j][top].id, r = S[j][top - ].id;
int t = val[i][j] - S[j][top].num;
ans[i][l] += t, ans[i][r] -= t;
top --;
}
S[j][++ top] = node(i, val[i][j]);
Q[j] = top;
}
}
for(int i = n; i; i --)
{
for(int j = i; j <= n; j ++)
ans[i][j] += ans[i][j - ];
for(int j = i; j <= n; j ++) ans[i][j] += ans[i + ][j];
for(int j = i; j <= n; j ++)
Ans = max(Ans, ans[i][j] - dis[j] + dis[i]);
}
printf("%lld\n", Ans);
return ;
}

最新文章

  1. hdu-2063-二分图最大匹配
  2. java integer对象判断两个数字是否相等
  3. POJ 3318 Matrix Multiplication(随机算法)
  4. Cheatsheet: 2013 09.22 ~ 09.30
  5. OS X 10.9 Mavericks 安装 thrift 0.9.1
  6. nslookup工具的使用方法
  7. Linux——搭建PHP开发环境第四步:composer
  8. 统计SQLSERVER表行数,以及每天数据变化的行数
  9. Airtest自动化测试工具
  10. ASP.NET Core Web App应用第三方Bootstrap模板
  11. 36 【kubernetes】coredns
  12. 10-Python3从入门到实战—基础之函数
  13. offsetHeight,scrollHeight,clientHeight,scrollTop以及pageX,clientX,offsetX,screenX,offsetLeft,style.left等的区别以及使用详解
  14. 浅入浅出Lambda表达式
  15. MYSQL判断不存在时创建表或创建数据库
  16. Xilinx vivado迅雷下载地址(所有版本)
  17. 数组序列化serialize
  18. 双机/RAC/Dataguard的区别【转】
  19. Python3.2官方文档翻译--标准库概览(一)
  20. checkbox选择框如果被选中value值就可以传过去,没有被选中value就不能穿过去(调试了近一天,坑爹的说)

热门文章

  1. ROS(一)Topic 通信
  2. HTML5 离线应用程序
  3. 引领技术变革,腾讯云、腾讯WeTest和英特尔,合作布局云游戏
  4. apache Subversion 直接支持LDAP域群组
  5. 「功能笔记」性能分析工具gprof使用笔记
  6. 阿里云ECS下Ubuntu 16.04系统安装python3.6.5 环境并设置为默认
  7. linux学习总结----redis总结
  8. 贪心算法——Huffman 压缩编码的实现
  9. solidity合约详解
  10. http://www.yiibai.com/javalang/string_endswith.html