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 }