zoukankan      html  css  js  c++  java
  • 题解「CSP2019 划分」

    (f_i)(1sim n) 划分成若干段得到的最小值,(g_i)(f_i) 转移过来的决策值。

    什么意思呢?我们有 ( ext{DP}) 转移方程:

    [f_i=min{f_j+(sum_i-sum_j)^2}(g_jleq sum_i-sum_j) ]

    那么 (g_i) 就为令上式取到最小值的 (sum_i-sum_j)

    这样就有了一个 (O(n^2)) 的做法,能够获得 (64 ext{pts})

    我们发现上式的约束可以改写为 (g_j+sum_jleq sum_i),又发现 (sum_i) 是单增的,这使我们想到用单调队列维护。正确性基于,最后一段我们希望它尽可能的小。于是时间复杂度优化为 (O(n))

    只能获得 (88 ext{pts}),由于没有高精/kk

    #include<cstdio>
    #define int ll
    typedef long long ll;
    int f[1000005],g[1000005],a[1000005],q[1000005];
    inline int read() {
    	register int x=0,f=1;register char s=getchar();
    	while(s>'9'||s<'0') {if(s=='-') f=-1;s=getchar();}
    	while(s>='0'&&s<='9') {x=x*10+s-'0';s=getchar();}
    	return x*f;
    } 
    signed main() {
    	int n=read(),type=read();
    	for(register int i=1;i<=n;++i) a[i]=a[i-1]+read();
    	int hd=0,tl=0; 
    	for(register int i=1;i<=n;++i) {
    		while(hd<tl&&a[q[hd+1]]+g[q[hd+1]]<=a[i]) ++hd;//g[q[hd+1]]<=a[i]-a[q[hd+1]]
    		g[i]=a[i]-a[q[hd]]; f[i]=f[q[hd]]+g[i]*1ll*g[i];
    		while(hd<=tl&&a[q[tl]]+g[q[tl]]>=a[i]+g[i]) --tl;
    		q[++tl]=i;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    pta建立与遍历二叉树
    Pikachu-SSRF(服务器端请求伪造)
    Pikachu-Sql Inject(SQL注入)
    Pikachu-RCE(远程命令/代码执行漏洞)
    Pikachu-php反序列化
    Pikachu-over permission(越权操作)
    Pikachu-File Inclusion(文件包含漏洞)
    Pikachu-CSRF(跨站请求伪造)
    CMS-熊海网站内容管理系统漏洞测试
    DVWA-命令执行
  • 原文地址:https://www.cnblogs.com/tommy0103/p/14065147.html
Copyright © 2011-2022 走看看