zoukankan      html  css  js  c++  java
  • hdu3480 Division(dp平行四边形优化)

    题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000

    题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想到dp

    分段dp十分好想吧,f[i][j]表示前i个数,分成j个数的最小值。

    w[i][j]区间包含性十分好证明,

    平行四边不等性,可以很好证明,

    对吧,这样很好理解

    所以得出f[i][j]满足------>s[i][j-1]<=s[i][j]<=s[i+1][j]

    这个得出来就ok了,但是这道题有点奇葩,s[i][j-1]以前就求好了,但是s[i+1][j]呢?所以

    需要倒着dp,先求s[i+1][j]在去搞s[i][j];

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #define inf 2000000009
     8 using namespace std;
     9 
    10 int cas,n,m,now=0;
    11 int a[10007];
    12 int f[10007][5007],s[10007][5007];
    13 
    14 int main()
    15 {
    16     scanf("%d",&cas);
    17     while(cas--)
    18     {
    19         scanf("%d%d",&n,&m);
    20         for (int i=1;i<=n;i++)
    21             scanf("%d",&a[i]);
    22         sort(a+1,a+n+1);
    23         for (int i=1;i<=n;i++)
    24             f[i][1]=(a[i]-a[1])*(a[i]-a[1]),s[i][1]=1;
    25         for (int k=2;k<=m;k++)
    26         {
    27             s[n+1][k]=n;
    28             for (int i=n;i>=k;i--)
    29             {
    30                 f[i][k]=inf;
    31                 for (int j=s[i][k-1];j<=s[i+1][k];j++)
    32                 {
    33                     int t=f[j-1][k-1]+(a[i]-a[j])*(a[i]-a[j]);
    34                     if (t<f[i][k]) f[i][k]=t,s[i][k]=j;    
    35                 }
    36             }
    37         }
    38         printf("Case %d: %d
    ",++now,f[n][m]);
    39     }
    40 }
  • 相关阅读:
    常用cmd命令总结
    百度地图api的简单应用(二):轻量级路径规划
    百度地图api的简单应用(一):POI检索
    R语言-八皇后问题
    8086基本IO口的仿真
    输入输出与中断
    汇编语言例子
    变量标号
    变量声明
    串操作指令2
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7689034.html
Copyright © 2011-2022 走看看