• HDU 2829 Lawrence


    HDU_2829

        设w[i][j]表示i到j的value,那么可以得到f[i][j]=min{f[i-1][k-1]+w[k][j]}(i<k<=j),如果直接dp的话是O(M*N^2)的复杂度。

        然而这个状态转移方程和POJ_1160的状态转移方程是一样的,因而只要我们能够证明w为凸的话,就可以证明f[i][j]为凸,那么就可以用四边形不等式进行优化了。

        要证w为凸,只要证w[i][j]+w[i+1][j+1]<=w[i][j+1]+w[i+1][j]即可,也就是证明w[i+1][j]-w[i][j]是关于j单调递减的。又因为w[i][j]=w[i+1][j]+(A[j]-A[i])*a[i],其中a[i]表示i点权,A[i]表示1,2,…,i的点权和,代入到w[i+1][j]-w[i][j]中就可以得到w[i+1][j]-w[i][j]=(A[i]-A[j])*a[i],显然是随j的增加而递减的。这样我们就证明出了w为凸,进而可以证明f[i][j]的求解可以用四边形不等式优化。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 1010
    #define INF 0x3f3f3f3f
    int f[MAXD][MAXD], w[MAXD][MAXD], K[MAXD][MAXD], N, M, a[MAXD], A[MAXD];
    void init()
    {
    int i, j, k;
    A[0] = 0;
    for(i = 1; i <= N; i ++)
    {
    scanf("%d", &a[i]);
    A[i] = a[i] + A[i - 1];
    }
    }
    void solve()
    {
    int i, j, k, p, t;
    for(i = 0; i <= N; i ++)
    {
    f[i][i] = K[i][i] = i;
    w[i][i] = 0;
    }
    for(p = 1; p <= N - M; p ++)
    for(i = 1; (j = i + p) <= N; i ++)
    w[i][j] = w[i + 1][j] + a[i] * (A[j] - A[i]);
    for(i = M + 1; i <= N; i ++)
    K[M + 1][i] = i;
    for(p = 1; p <= N - M; p ++)
    {
    f[0][p] = w[1][p];
    for(i = 1; i <= M; i ++)
    f[i][i + p] = INF;
    for(i = 1; i <= M; i ++)
    {
    j = i + p;
    for(k = K[i][j - 1]; k <= K[i + 1][j]; k ++)
    if((t = f[i - 1][k - 1] + w[k][j]) < f[i][j])
    {
    f[i][j] = t;
    K[i][j] = k;
    }
    }
    }
    printf("%d\n", f[M][N]);
    }
    int main()
    {
    for(;;)
    {
    scanf("%d%d", &N, &M);
    if(!N && !M)
    break;
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    rsync同步公网yum源搭建本地yum仓库
    为smokeping添加日志开启debug
    python中if __name__ == '__main__':的作用
    使用telnet访问百度
    RRDtool绘制lvs连接数图形
    HTML表格
    ip netns
    redis动态扩展内存
    route命令
    设置nginx日志滚动
  • 原文地址:https://www.cnblogs.com/staginner/p/2394000.html
Copyright © 2020-2023  润新知