码迷,mamicode.com
首页 > 其他好文 > 详细

【HDOJ】【2829】Lawrence

时间:2015-03-06 12:32:43      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

DP/四边形不等式


  做过POJ 1739 邮局那道题后就很容易写出动规方程:

    dp[i][j]=min{dp[i-1][k]+w[k+1][j]}(表示前 j 个点分成 i 块的最小代价)

  $w(l,r)=\sum_{i=l}^{r}\sum_{j=i+1}^{r}a[i]*a[j]$

  那么就有 $w(l,r+1)=w(l,r)+a[j]*\sum\limits_{i=l}^{r}a[i]$

  所以:w[i][j]明显满足 关于区间包含的单调性

  然后我们大胆猜想,小(bu)心(yong)证明,w[i][j]满足四边形不等式,所以这题就跟邮局那题一样了……

 

  咳咳好吧作为一个有节操的人,我还是尝试着证明了一下(结果发现用来证明的时间比我写代码的时间要长……)

  先把w(i,j)的定义搬下来:\[ w(l,r)=\sum\limits_{i=l}^{r}\sum\limits_{j=i+1}^{r}a[i]*a[j] \]

  形象一点来说就是:

    对于$ i\leq i‘ < j \leq j‘ $

    中间的都是要算两次,剩下的部分:

      (左)表示w(i,i‘-1),[左]表示 $\sum_{k=i}^{i‘-1}a[k] $

      (中)表示w(i‘,j),[中]表示 $\sum_{k=i‘}^j a[k] $

      (右)表示w(j+1,j‘),[右]表示 $\sum_{k=j+1}^{j‘} a[k] $

    \[ w(i,j)+w(i‘,j‘)=(左)+[左]*[中]+(右)+[右]*[中] \\ w(i,j‘)+w(i‘,j)=(左+右)+[左+右]*[中]  \]

    

    其中\[ [左+右]*[中]=[左]*[中]+[右]*[中]  \]

    但\[ (左+右)=(左)+(右)+[左]*[右] \]

    所以\[ (左+右)>(左)+(右) \]

    所以\[w(i,j)+w(i‘,j‘) \leq w(i,j‘)+w(i‘,j) \]  

技术分享
 1 //HDOJ 2829
 2 #include<cmath>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 #define pb push_back
13 #define CC(a,b) memset(a,b,sizeof(a))
14 using namespace std;
15 int getint(){
16     int v=0,sign=1; char ch=getchar();
17     while(!isdigit(ch)) {if(ch==-) sign=-1; ch=getchar();}
18     while(isdigit(ch))  {v=v*10+ch-0; ch=getchar();}
19     return v*sign;
20 }
21 const int N=1010,INF=~0u>>2;
22 const double eps=1e-8;
23 #define debug
24 /*******************template********************/
25 int dp[N][N],s[N][N],w[N][N],b[N],a[N],n,m;
26 
27 int main(){
28     while(scanf("%d%d",&n,&m)!=EOF && n){
29         m++;
30         F(i,1,n) a[i]=getint();
31         F(i,1,n){
32             b[i]=a[i];
33             w[i][i]=0;
34             F(j,i+1,n){
35                 w[i][j]=w[i][j-1]+a[j]*b[i];
36                 b[i]+=a[j];
37             }
38         }
39         F(i,1,n) F(j,1,m) dp[j][i]=INF;
40         F(i,1,n){
41             dp[1][i]=w[1][i];
42             s[1][i]=0;
43         }
44         F(i,2,m){
45             s[i][n+1]=n;
46             D(j,n,i)
47                 F(k,s[i-1][j],s[i][j+1])
48                     if(dp[i-1][k]+w[k+1][j]<dp[i][j]){
49                         s[i][j]=k;
50                         dp[i][j]=dp[i-1][k]+w[k+1][j];
51                     }
52         }
53         printf("%d\n",dp[m][n]);
54     }
55     return 0;
56 }
View Code

 

【HDOJ】【2829】Lawrence

标签:

原文地址:http://www.cnblogs.com/Tunix/p/4317807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!