zoukankan      html  css  js  c++  java
  • AT2289 [ARC067D] Yakiniku Restaurants(水题)

    AT2289 [ARC067D] Yakiniku Restaurants(水题)

    题目大意

    有编号从 $ 1 $ 到 $ N $ 的 $ N $ 家烧烤店,烧烤店在一条线上按照编号顺序排序,第 $ i $ 家烧烤店与第 $ i + 1 $ 家烧烤店的距离是 $ A_i $ 。
    你有编号从 $ 1 $ 到 $ M $ 的 $ M $ 张烧烤券,不管是在哪一家烧烤店都可用烧烤券来吃烧烤,在第 $ i $ 家烧烤店用烧烤券 $ j $ 可以吃到一顿美味度为 $ B_{i,j} $ 的烧烤,每一张烧烤券只能使用一次,但是在一家烧烤店你可以使用任意多张烧烤券。
    你想从自己选择的一家烧烤店开始(随意选择一个开始),然后不断地用未使用的烧烤券去另一家烧烤店。你最终的幸福值是所吃所有烧烤的美味度减去所走的总路程。求最大可能的最终幸福值( $ M $ 张券必须用完)。

    数据范围

    输入的数字都是整数
    $ 2 leq N leq 5 imes 10^3 $

    $ 1 leq M leq 200 $

    $ 1 leq A_i leq 10^9 $

    $ 1 leq B_{i,j} leq 10^9 $

    解题思路

    容易发现选择的肯定是一条线段而且两端必选。

    所以我们从右边开始枚举左端点,维护一个答案数组 (tans[j]) 表示目前左端点固定,右端点在 j 的最优答案,接下来操作就是左端点向左移动一格,并更新答案扫一遍。

    如何更新答案,单独考虑每张票,只可能是从某个位置买换到左端点买,这里要求原来的某个位置获利比这个位置小,所以我们可以用一个单调栈来维护前缀最大值,然后差分前缀和即可。

    const int N = 5005, M = 205;
    ll d[N], b[M][N], ans, n, m;
    int st[M][N], tp[M]; ll t[N], tans[N];
    inline void add(int l, int r, ll k) { t[l] += k, t[r+1] -= k; }
    int main() {
    //	freopen ("hs.in","r",stdin);
    	read(n), read(m);
    	for (int i = 1;i < n; i++) read(d[i]);
    	for (int i = 1;i <= n; i++) 
    		for (int j = 1;j <= m; j++)
    			read(b[j][i]);
    	for (int i = 1;i <= m; i++) 
    		st[i][tp[i] = 1] = n + 1, b[i][n + 1] = 1e15;
    	for (int i = n;i >= 1; i--) {
    		for (int j = 1;j <= m; j++) {
    			ll *B = b[j]; int *St = st[j], &T = tp[j]; add(i, i, B[i]);
    			while (B[St[T]] <= B[i]) add(St[T], St[T-1]-1, B[i] - B[St[T]]), T--;
    			St[++T] = i;
    		}
    		add(i + 1, n, -d[i]);
    		ll res = 0;
    		for (int j = i;j <= n; j++)
    			res += t[j], t[j] = 0, tans[j] += res, Mx(ans, tans[j]); 
    	}
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    python流程控制
    数据类型
    python之初接触
    使用 HttpWebRequest 向网站提交数据
    在 ASP.NET MVC4 中使用 NInject
    第一篇 微信商城 开发前的准备工作
    (一)模块基础
    函数之递归、匿名函数及内置方法
    装饰器的使用原理
    mybatis返回list
  • 原文地址:https://www.cnblogs.com/Hs-black/p/13627705.html
Copyright © 2011-2022 走看看