TYVJ 1215 斜率优化DP

题目连接:http://new.tyvj.cn/Problem_Show.aspx?id=1215

思路:

方程再简单不过了:

dp[i]表示以第i个人为某一组最后一个人的总战斗值

dp[i]=max(dp[j]+F(sum[i]-sum[j]))

其中F(x)=A*x*x+B*x+C       sum[i]表示战斗值的前缀和

显然n^2的方程,只能得到20分

 

单调性显然,那么就开始我们的斜率优化

设j<k且满足k比j更优

dp[j]+A*(sum[i]-sum[j])^2+B*(sum[i]-sum[j])+C<=dp[k]+A*(sum[i]-sum[k])^2+B*(sum[i]-sum[k])+C

化简,分离变量,将含j,k的结构放到方程一边,含i的结构放在方程另一边:

2*A*sum[i]*(sum[k]-sum[j])<=dp[k]-dp[j]+B*(sum[j]-sum[k])+A*(sum[k]^2-sum[j]^2)

设:

p[i]=2*A*sum[i]

G(k,j)=dp[k]-dp[j]+B*(sum[j]-sum[k])+A*(sum[k]^2-sum[j]^2)

S(k,j)=sum[k]-sum[j]

W(k,j)=G(k,j)/S(k,j)

所以只要维护   :   W(k,j)>=p[i]   就可以了~

(PS:如果没有看懂斜率优化,请转步:http://www.cnblogs.com/proverbs/archive/2012/10/06/2713109.html

 

 

View Code
 1 #include <cstdio>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <iostream>

 5 

 6 #define N 1001000

 7 

 8 using namespace std;

 9 

10 __int64 A,B,C,a[N],sum[N],dp[N],p[N];

11 int n,q[N];

12 

13 void read()

14 {

15     scanf("%d",&n);

16     scanf("%I64d%I64d%I64d",&A,&B,&C);

17     for(int i=1;i<=n;i++)

18     {

19         scanf("%I64d",&a[i]);

20         sum[i]=sum[i-1]+a[i];

21         p[i]=2*A*sum[i];

22     }

23 }

24 

25 inline __int64 G(int y,int x)

26 {

27     return dp[y]-dp[x]+B*(sum[x]-sum[y])+A*(sum[y]*sum[y]-sum[x]*sum[x]);

28 }

29 

30 inline __int64 S(int y,int x)

31 {

32     return sum[y]-sum[x];

33 }

34 

35 inline __int64 F(int x)

36 {

37     return A*x*x+B*x+C;

38 }

39 

40 void go()

41 {

42     dp[0]=0;

43     int h=1,t=1;

44     q[t++]=0;

45     for(int i=1,x,y,z;i<=n;i++)

46     {

47         while(h<t-1&&G(q[h+1],q[h])>=p[i]*S(q[h+1],q[h])) h++;

48         

49         dp[i]=dp[q[h]]+F(sum[i]-sum[q[h]]);

50         

51         q[t++]=i;

52         

53         for(int j=t-2;j-1>=h;j--)

54         {

55             x=q[j-1]; y=q[j]; z=q[j+1];

56             if(G(z,y)*S(y,x)>=G(y,x)*S(z,y)) q[j]=q[--t];

57             else break;

58         }

59     }

60     printf("%I64d\n",dp[n]);

61 }

62 

63 int main()

64 {

65     read();

66     go();

67     return 0;

68 }

 

 

 

你可能感兴趣的:(优化)