题目链接:hdu 2829 Lawrence
题意:
在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和.。然后给你m个炮弹,让你选择破坏掉m段铁路,使剩下的整条铁路的战略价值最小。
题解:
和hdu 3480 Division(斜率优化DP)这题相同,只是方程不同而已,改改就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const int N=1007; 6 7 int n,m,dp[2][N],sum[N],cost[N],Q[N]; 8 9 int gety(int i,int j,int k){return dp[i][j]-cost[j]+sum[j]*sum[j]-(dp[i][k]-cost[k]+sum[k]*sum[k]);} 10 int getx(int i,int j){return sum[i]-sum[j];} 11 int check(int i,int j,int k,int l){return gety(i,j,k)*getx(k,l)<=gety(i,k,l)*getx(j,k);} 12 13 14 15 int main() 16 { 17 while(scanf("%d%d",&n,&m),n+m) 18 { 19 m++; 20 F(i,1,n) 21 { 22 scanf("%d",sum+i); 23 cost[i]=cost[i-1]+sum[i]*sum[i-1]; 24 sum[i]+=sum[i-1]; 25 } 26 F(i,1,n)dp[0][i]=cost[i]; 27 F(i,2,m) 28 { 29 int head=1,tail=0; 30 Q[++tail]=i-1; 31 F(j,i,n) 32 { 33 while(head<tail&&check(i&1,j,Q[tail],Q[tail-1]))tail--; 34 Q[++tail]=j; 35 while(head<tail&&gety(i&1,Q[head+1],Q[head])<=getx(Q[head+1],Q[head])*sum[j])head++; 36 dp[(i&1)^1][j]=dp[i&1][Q[head]]+cost[j]-cost[Q[head]]-sum[Q[head]]*(sum[j]-sum[Q[head]]); 37 } 38 } 39 printf("%d ",dp[(m+1)&1][n]); 40 } 41 return 0; 42 }