zoukankan      html  css  js  c++  java
  • HDU 3480 Division

    HDU_3480

        首先,一个贪心的思路就是如果将元素排个序,选择的一定是连续的区间,因为如果选了两个值,那么这个区间就可以选两个值之间的任何一个值,这样是不会改变这个区间的cost的。

        如果用w[i][j]表示(a[j]-a[i])*(a[j]-a[i]),写出状态转移方程后会得到f[i][j]=min{f[i-1][k-1]+w[k,j]},这个和POJ_1160的状态转移方程是一样的,如果我们能够证明w为凸,那么这个题就可以用四边形不等式优化。

        由于w[i+1][j]-w[i][j]=(a[i]-a[i+1])*(2*a[j]-a[i+1]-a[i]),这个表达式是随着j的增加单调递减的,所以就有w[i+1][j+1]-w[i][j+1]<=w[i+1][j]-w[i][j],也就是w[i][j]+w[i+1][j+1]<=w[i][j+1]+w[i+1][j],所以w是凸的,进而我们就可以放心地使用四边形不等式优化dp了。

        其实,如果我们把状态转移方程写成f[i][j]=min{f[i-1][k-1]+ (a[j]-a[k])*(a[j]-a[k])}的话,不妨假设k的取值x、y满足x<y,且y要比x优,这时就能化简成a[j]>(a[y]*a[y]-a[x]*a[x]+f[i-1][y-1]-f[i-1][x-1])/(2*a[y]-2*a[x]),这样就又变成能够使用斜率优化了,而且用斜率优化比较好用滚动数组实现,能节省不少空间。

    //四边形不等式优化dp
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 10010
    #define INF 0x3f3f3f3f
    int N, M, a[MAXD], f[MAXD][MAXD], K[MAXD][MAXD];
    int cmp(const void *_p, const void *_q)
    {
    int *p = (int *)_p, *q = (int *)_q;
    return *p - *q;
    }
    int getw(int x, int y)
    {
    return (a[y] - a[x]) * (a[y] - a[x]);
    }
    void init()
    {
    int i, j, k;
    scanf("%d%d", &N, &M);
    for(i = 1; i <= N; i ++)
    scanf("%d", &a[i]);
    }
    void solve()
    {
    int i, j, k, p, t;
    qsort(a + 1, N, sizeof(a[0]), cmp);
    for(i = 0; i <= N; i ++)
    {
    f[i][i] = 0;
    K[i][i] = i;
    }
    for(i = M + 2; i <= N; i ++)
    K[M + 1][i] = i;
    for(p = 1; p <= N - M; p ++)
    {
    f[0][p] = INF;
    for(i = 1; i <= M; i ++)
    {
    j = i + p;
    f[i][j] = INF;
    for(k = K[i][j - 1]; k <= K[i + 1][j]; k ++)
    {
    t = f[i - 1][k - 1] + getw(k, j);
    if(t < f[i][j])
    {
    f[i][j] = t;
    K[i][j] = k;
    }
    }
    }
    }
    printf("%d\n", f[M][N]);
    }
    int main()
    {
    int t, tt;
    scanf("%d", &t);
    for(tt = 0; tt < t; tt ++)
    {
    init();
    printf("Case %d: ", tt + 1);
    if(M >= N)
    printf("0\n");
    else
    solve();
    }
    return 0;
    }
    //斜率优化+单调队列
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 10010
    int N, M, a[MAXD], wa[MAXD], wb[MAXD], *f, *g, q[MAXD];
    int cmp(const void *_p, const void *_q)
    {
    int *p = (int *)_p, *q = (int *)_q;
    return *p - *q;
    }
    void init()
    {
    int i, j, k;
    scanf("%d%d", &N, &M);
    for(i = 1; i <= N; i ++)
    scanf("%d", &a[i]);
    }
    int getw(int x, int y)
    {
    return (a[y] - a[x]) * (a[y] - a[x]);
    }
    int getf(int i)
    {
    return a[i] * a[i] + g[i - 1];
    }
    void solve()
    {
    int i, j, k, front, rear, x, y, z, *t;
    qsort(a + 1, N, sizeof(a[0]), cmp);
    f = wa, g = wb;
    for(i = 1; i <= N; i ++)
    g[i] = getw(1, i);
    for(i = 2; i <= M; i ++)
    {
    front = rear = 0;
    q[rear ++] = i;
    for(j = i; j <= N; j ++)
    {
    while(front < rear - 1)
    {
    x = q[front], y = q[front + 1];
    if(a[j] * 2 * (a[y] - a[x]) < getf(y) - getf(x))
    break;
    ++ front;
    }
    x = q[front];
    f[j] = g[x - 1] + getw(x, j);
    if(j < N)
    {
    q[rear] = j + 1;
    for(k = rear - 1; k > front; k --)
    {
    x = q[k - 1], y = q[k], z = q[k + 1];
    if((getf(y) - getf(x)) * (a[z] - a[y]) < (getf(z) - getf(y)) * (a[y] - a[x]))
    break;
    q[rear = k] = q[k + 1];
    }
    ++ rear;
    }
    }
    t = f, f = g, g = t;
    }
    printf("%d\n", g[N]);
    }
    int main()
    {
    int t, tt;
    scanf("%d", &t);
    for(tt = 0; tt < t; tt ++)
    {
    init();
    printf("Case %d: ", tt + 1);
    if(M >= N)
    printf("0\n");
    else
    solve();
    }
    return 0;
    }



  • 相关阅读:
    [MacOS]Sublime text3 安装(一)
    [RHEL8]开启BBR
    PAT Advanced 1136 A Delayed Palindrome (20分)
    PAT Advanced 1144 The Missing Number (20分)
    PAT Advanced 1041 Be Unique (20分)
    PAT Advanced 1025 PAT Ranking (25分)
    PAT Advanced 1022 Digital Library (30分)
    PAT Advanced 1019 General Palindromic Number (20分)
    PAT Advanced 1011 World Cup Betting (20分)
    PAT Advanced 1102 Invert a Binary Tree (25分)
  • 原文地址:https://www.cnblogs.com/staginner/p/2394329.html
Copyright © 2011-2022 走看看