BZOJ 1010: [HNOI2008]玩具装箱toy(DP+斜率优化)

题目链接

参考题解,解方程都解错。。和HDU3507 有点类似。其中还要运用换元,数学能力太弱了。

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <stdlib.h>

 4 #define N  500001

 5 long long dp[N],que[N],p[N],sum[N];

 6 int m;

 7 double slope(int x,int y)

 8  {

 9      if(sum[x] == sum[y])

10      {

11          if(dp[x] > dp[y])

12          return -1;

13          else

14          return 2147483647;

15      }

16      return (dp[x]-dp[y]+sum[x]*sum[x]-sum[y]*sum[y])*1.0/(sum[x]-sum[y]);

17  }

18 int main()

19 {

20     int n,i,str,end;

21     scanf("%d%d",&n,&m);

22     m ++;

23     for(i = 1; i <= n; i ++)

24     {

25         scanf("%lld",&p[i]);

26         sum[i] = p[i]+sum[i-1];

27     }

28     for(i = 1; i <= n; i ++)

29     {

30         sum[i] = sum[i] + i;

31     }

32     str = end = 0;

33     for(i = 1; i <= n; i ++)

34     {

35         while(str < end&&slope(que[str],que[str+1]) <= 2*(sum[i]-m))

36             str ++;

37         dp[i] = dp[que[str]] + (sum[i]-sum[que[str]]-m)*(sum[i]-sum[que[str]]-m);

38         while(str < end&&slope(que[end-1],que[end]) >= slope(que[end],i))

39             end --;

40         end ++;

41         que[end] = i;

42     }

43     printf("%lld\n",dp[n]);

44     return 0;

45 }

 

你可能感兴趣的:(2008)