zoukankan      html  css  js  c++  java
  • AcWing 334. K匿名序列

    大型补档计划

    题目链接

    就是把序列分成无数段,每段长度 $ >= K$,然后 ([l, r]) 这段的花费是 (S[r] - S[l - 1] - (r - l + 1) * a[l]) (把所有数减成 (a[l])

    很容易列出状态转移方程:
    (f[i]) 为前 i 个分完段的最小花费
    (f[i] = f[j] + s[i] - s[j] - (i - j) * a[j + 1])
    移项:
    (underline{f[j] - s[j] + j * a[j + 1]}_y = underline{i}_k * underline{a[j + 1]}_x - underline{s[i] + f[i]}_b)

    一个鲜明的斜率优化,其中斜率、横坐标都是递增的,用弹出法即可。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int N = 500005;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    
    int n, K, a[N], q[N];
    LL f[N], s[N];
    LL inline y(int i) { return f[i] - s[i] + i * (LL)a[i + 1]; } 
    LL inline x(int i) { return a[i + 1]; }
    int main() {
    	int T; scanf("%d", &T);
    	while (T--) {
    		memset(f, 0x3f, sizeof f);
    		scanf("%d%d", &n, &K);
    		for (int i = 1; i <= n; i++) 
    			scanf("%d", a + i), s[i] = s[i - 1] + a[i];
    		f[0] = 0;
    		int hh = 0, tt = 0;
    		for (int i = K; i <= n; i++) {
    		    if (i - K >= K) {
        			while (hh < tt && (y(q[tt]) - y(q[tt - 1])) * (x(i - K) - x(q[tt])) >= (y(i - K) - y(q[tt])) * (x(q[tt]) - x(q[tt - 1]))) tt--;
        			q[++tt] = i - K;
    			}  
    			while (hh < tt && y(q[hh + 1]) - y(q[hh]) <= i * (x(q[hh + 1]) - x(q[hh]))) hh++;
    			if (hh <= tt) f[i] = f[q[hh]] + s[i] - s[q[hh]] - (LL)(i - q[hh]) * a[q[hh] + 1];
    		}
    		printf("%lld
    ", f[n]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    [LeetCode 题解]: Remove Duplicates from Sorted List
    [LeetCode 题解]: Merge k Sorted Lists
    [LeetCode 题解]: Insertion Sort List
    [LeetCode 题解]:Candy
    求任意多边形面积 python实现
    C++飞机大战
    version robot
    python一段代码 感受一下
    微机原理上机第四次实验内容
    初步的百度爬虫
  • 原文地址:https://www.cnblogs.com/dmoransky/p/12380602.html
Copyright © 2011-2022 走看看