zoukankan      html  css  js  c++  java
  • 【HDU】2829 Lawrence

    http://acm.hdu.edu.cn/showproblem.php?pid=2829

    题意:将长度为n的序列分成p+1块,使得$sum_{每块}sum_{i<j} a[i]a[j]$最小(n<=1000,1<=a[i]<=100)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <iostream>
    using namespace std;
    const int N=10005;
    typedef long long ll;
    ll d[2][N], s1[N], s2[N];
    int n, p, x[N], s[2][N];
    inline ll sqr(ll a) { return a*a; }
    inline ll w(int l, int r) { return (sqr(s1[r]-s1[l-1])-(s2[r]-s2[l-1]))>>1; }
    int main() {
    	while(scanf("%d%d", &n, &p), !(n==0&&p==0)) {
    		++p;
    		for(int i=1; i<=n; ++i) scanf("%d", &x[i]), s1[i]=s1[i-1]+x[i], s2[i]=s2[i-1]+sqr(x[i]);
    		int h=0, t=1;
    		for(int i=2; i<=n; ++i) d[h][i]=w(1, i), s[h][i]=1;
    		for(int i=2; i<=p; ++i) {
    			s[t][n+1]=n;
    			for(int j=n; j>=1; --j) {
    				int l=s[h][j], r=s[t][j+1], &pos=s[t][j]; ll &now=d[t][j];
    				now=~0ull>>1;
    				for(int k=l; k<=r; ++k) {
    					ll t=d[h][k-1]+w(k, j);
    					if(now>=t) now=t, pos=k;
    				}
    			}
    			swap(t, h);
    		}
    		printf("%lld
    ", d[h][n]);
    	}
    	return 0;
    }
    

      

    设$d(i, j)$表示分$i$份前$j$个的最小代价,容易得到

    $$d(i, j) = min { d(i-1, k-1) + w(k, j) }, i<j $$

    其中

    $$w(i, j) = frac{sum1(i, j)^2-sum2(i, j)}{-2}$$

    其中$sum1(i, j)=sum_{i}^{j} a[i], sum2(i, j)=sum_{i}^{j} a[i]^2$

    (可以由$(sum_{i} a[i] )^2 = sum_{i} a[i]^2 - 2 sum_{i<j} a[i]a[j]$得到= =,然后$O(n)$求出来,虽然你们都是用$O(n^2)$预处理的= =(我有常数强迫症= =))

    证明挺好证的(这里只证明$w$的四边形不等式,剩下证明与前面两题相同= =我就不证明了= =

    证明四边形不等式即证明当$j$固定时,$w(i, j+1)-w(i, j)$是关于$i$的递减函数

    $$
    egin{align}
    & w(i, j+1)-w(i, j) otag \
    = & frac{sum1(i, j+1)^2-sum2(i, j+1)}{-2} - frac{sum1(i, j)^2-sum2(i, j)}{-2} \
    = & frac{sum1(i, j+1)^2 - sum1(i, j)^2 + sum2(i, j) - sum2(i, j+1)}{-2} \
    = & frac{a[j+1]^2 - 2a[j+1]sum_{k=i}^{j} a[k] - a[j+1]^2}{-2} \
    = & a[j+1]sum_{k=i}^{j} a[k]
    end{align}
    $$

    当j不变时i递增,显然式子减小,得证。

  • 相关阅读:
    Elasticsearch入门系列(一)
    清楚Chrome缓存
    解决IIS启动站点报错
    Input type="file"上传文件change事件只触发一次解决方案
    本地计算机上的XXX服务启动后停止,某些服务在未由其它服务或程序使用时将自动停止
    SQL Server Datetime类型为NULL不能用ISNULL(datetime,' ')来判断,会导致1900-01-01
    浏览指南
    谁发明的c++
    c++的用处
    不一样的二叉树遍历(小学生都会)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4324406.html
Copyright © 2011-2022 走看看