hdu 2829 Lawrence(斜率优化DP)

题目链接:hdu 2829 Lawrence

题意:

在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和.。然后给你m个炮弹,让你选择破坏掉m段铁路,使剩下的整条铁路的战略价值最小。

题解:

hdu 3480 Division(斜率优化DP)这题相同,只是方程不同而已,改改就行了。

 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 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/6142518.html