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

    _(:3」∠)_

    dp[i][j]:前i个分j组的最小值

    cost[i][j]:i到j为一组的值

    sum[i]:前i个的值的总和

    dp[i][j]=min{dp[k][j-1]+cost[k+1][i]}

    cost[k+1][i]=cost[1][i]-cost[1][k]-sum[k]*(sum[i]-sum[k])=cost[i]-cost[k]+sum[k]*sum[k]-sum[k]*sum[i]

    令y=dp[k][j-1]-cost[k]+sum[k]*sum[k]

    则dp[i][j]=min{y+cost[i]-sum[k]*sum[i]}

    sum[i]为斜率

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<iostream>
     6 #include<queue>
     7 #include<stack>
     8 #include<cmath>
     9 #include<map>
    10 #define BUG printf("hehe
    ")
    11 #define INF 0x3f3f3f3f
    12 #define ll long long
    13 using namespace std;
    14 
    15 int cost[1010],sum[1010];
    16 int dp[1010][1010],q[1010];
    17 int n,m,head,tail;
    18 
    19 int dx(int a,int b)
    20 {
    21     return sum[a]-sum[b];
    22 }
    23 
    24 int dy(int x,int a,int b)
    25 {
    26     return dp[a][x]-cost[a]+sum[a]*sum[a]-(dp[b][x]-cost[b]+sum[b]*sum[b]);
    27 }
    28 
    29 int main()
    30 {
    31     int t;
    32     while(scanf("%d%d",&n,&m)&&(n|m)) {
    33         sum[0]=0;
    34         cost[0]=0;
    35         for(int i=1;i<=n;++i) {
    36             scanf("%d",&t);
    37             sum[i]=sum[i-1]+t;
    38             cost[i]=cost[i-1]+t*sum[i-1];
    39         }
    40         for(int i=1;i<=n;++i)
    41             dp[i][1]=cost[i];
    42 
    43         for(int j=2;j<=m+1;++j) {
    44             head=0,tail=-1;
    45             q[++tail]=j-1;
    46             for(int i=j;i<=n;++i) {
    47                 while(head<tail&&(dy(j-1,q[head+1],q[head])<sum[i]*dx(q[head+1],q[head]))) ++head;
    48                 dp[i][j]=dp[q[head]][j-1]-cost[q[head]]+sum[q[head]]*sum[q[head]]+
    49                             cost[i]-sum[i]*sum[q[head]];
    50                 while(head<tail&&(dy(j-1,i,q[tail])*dx(q[tail],q[tail-1])
    51                       <=dy(j-1,q[tail],q[tail-1])*dx(i,q[tail]))) --tail;
    52                 q[++tail]=i;
    53             }
    54         }
    55         printf("%d
    ",dp[n][m+1]);
    56     }
    57 }

    四边形优化:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<map>
    #define BUG printf("hehe
    ")
    #define INF 0x3f3f3f3f
    #define ll long long
    using namespace std;
    
    int cost[1010][1010],sum[1010];
    int s[1010][1010];
    int dp[1010][1010];
    int a[1010];
    int n,m,head,tail;
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)&&(n|m)) {
            sum[0]=0;
            for(int i=1;i<=n;++i) {
                scanf("%d",a+i);
                sum[i]=sum[i-1]+a[i];
            }
            memset(cost,0,sizeof cost);
            for(int i=1;i<=n;++i)
            for(int j=i+1;j<=n;++j) {
                cost[i][j]=cost[i][j-1]+a[j]*(sum[j-1]-sum[i-1]);
            }
            for(int i=0;i<=n;++i) {
                dp[i][1]=cost[1][i];
                s[i][1]=1;
                s[n+1][i]=n-1;
            }
            for(int j=2;j<=m+1;++j) {
                for(int i=n;i>=1;--i) {
                    dp[i][j]=INF;
                    for(int k=s[i][j-1];k<=s[i+1][j];++k) {
                        if(dp[k][j-1]+cost[k+1][i]<dp[i][j]) {
                            s[i][j]=k;
                            dp[i][j]=dp[k][j-1]+cost[k+1][i];
                        }
                    }
                }
            }
            printf("%d
    ",dp[n][m+1]);
        }
    }
  • 相关阅读:
    Winform架构
    SQL2008多数据库查询表或删表
    hdu1114 PiggyBank
    hdu2844 Coins
    hdu2602 Bone Collector
    hdu2191 珍惜现在
    hdu1203 I NEED A OFFER!
    求推荐
    TransparentBlt
    双缓冲加载位图 WinCE
  • 原文地址:https://www.cnblogs.com/morimiya/p/3646010.html
Copyright © 2011-2022 走看看