zoukankan      html  css  js  c++  java
  • BZOJ1233 [Usaco2009Open]干草堆tower

    一道单调队列优化(DP)

    原题链接

    首先想到的应该是(O(n^3))的朴素(DP)
    定义(f[i][j])表示第(jsim i)块干草堆作为顶层时的最大高度。

    (qquadqquad f[i][j]=maxlimits_{k=1}^{j-1}{f[j-1][k]}+1,(sum[i]-sum[j-1]leqslant sum[j-1]-sum[k-1]))

    但显然时间空间全炸了,这时我们需要知道一个结论,即最优解的最底层在所有解中一定是最小的(下面越窄才能叠的越高)。

    任意取出一个能使层数最高的方案,设有CA层,把其中从下往上每一层最大的块编号记为Ai;任取一个能使底边最短的方案,设有CB层,把其中从下往上每一层最大的块编号记为Bi。显然A1>=B1,ACB<=BCB,这说明至少存在一个k属于(1,CB),满足Ak-1>=Bk-1且Ak<=Bk。也就是说,方案 A 第K 层完全被方案 B 第K 层包含。构造一个新方案,第K 层往上按方案 A,往下按方案 B,两边都不要的块放中间当第K 层。新方案的层数与 A 相同,而底边长度与 B 相同。证毕。
    证明by zkw

    因为正着推并不单调,所以我们要倒着来推。
    定义(f[i])表示第(isim n)块干草堆构成的塔的最底层的宽度,(h[i])表示状态(f[i])下的最大高度。

    (qquadqquad f[i]=minlimits_{j=i+1}^n{sum[j-1]-sum[i-1]},(f[j]leqslant sum[j-1]-sum[i-1]))

    (qquadqquad h[i]=h[j]+1)

    时间复杂度(O(n^2))
    显然(j)越小越好。
    (f[i])的转移方程条件移项得(sum[i-1]leqslant sum[j-1]-f[j]),所以对于一个决策(k),如果有一个决策(j)满足(k>j ext{且}sum[k-1]-f[k]leqslant sum[j-1]-f[j]),即可认为(k)是无用决策。
    这样就可以用单调队列来维护了。

    #include<cstdio>
    using namespace std;
    const int N = 1e5 + 10;
    int f[N], h[N], a[N], q[N];
    int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c<'0' || c>'9'; c = getchar())
    		p = (c == '-' || p) ? 1 : 0;
    	for (; c >= '0'&&c <= '9'; c = getchar())
    		x = x * 10 + (c - '0');
    	return p ? -x : x;
    }
    int main()
    {
    	int i, l = 1, r = 1, n;
    	n = re();
    	for (i = 1; i <= n; i++)
    		a[i] = a[i - 1] + re();
    	for (i = n, q[1] = n + 1; i; i--)
    	{
    		while (l < r && f[q[l + 1]] <= a[q[l + 1] - 1] - a[i - 1])
    			l++;
    		f[i] = a[q[l] - 1] - a[i - 1];
    		h[i] = h[q[l]] + 1;
    		while (l <= r && a[q[r] - 1] - f[q[r]] <= a[i - 1] - f[i])
    			r--;
    		q[++r] = i;
    	}
    	printf("%d", h[1]);
    	return 0;
    }
    
  • 相关阅读:
    软件工程,实践作业1_团队博客
    软件工程,实践作业1
    c# excel 读写 64位操作系统 64位excel
    pyfits fits图像区域选择
    python numpy中sum()时出现负值
    python 中模块的版本号
    numpy rand函数的应用
    python 字符串是否包含某个子字符串
    python 字符串格式化
    python 让异常名称显示出来
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9509844.html
Copyright © 2011-2022 走看看