BZOJ 1096 [ZJOI2007]仓库建设

转移特别显然是n^2的,tle~

然后由于转移没有区间限制,所以应该不是单调队列,然后想斜率优化吧。

推了两张纸,证明了决策的单调性(我以前都是默认的单调。。。第一次证明。),嘿嘿。

其实就是维护的一个下凸的函数。

 

View Code
 1 #include <iostream>

 2 #include <algorithm>

 3 #include <cstdio>

 4 #include <cstdlib>

 5 #include <cstring>

 6 

 7 #define N 1100000

 8 

 9 using namespace std;

10 

11 int n;

12 long long x[N],p[N],sump[N],sum[N],c[N],dp[N],q[N];

13 

14 inline void read()

15 {

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

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

18     {

19         scanf("%lld%lld%lld",&x[i],&p[i],&c[i]);

20         sump[i]=sump[i-1]+p[i];

21         sum[i]=sum[i-1]+p[i]*x[i];

22     }

23 }

24 

25 inline long long V(int u,int s)

26 {

27     return dp[u]+sum[u]-dp[s]-sum[s];

28 }

29 

30 inline long long G(int u)

31 {

32     return x[u]*sump[u]-sum[u]+c[u];

33 }

34 

35 inline void go()

36 {

37     int h=1,t=1;

38     q[1]=0;

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

40     {

41         while(h<t&&V(q[h+1],q[h])<x[i]*(sump[q[h+1]]-sump[q[h]])) h++;

42         dp[i]=dp[q[h]]+sum[q[h]]-x[i]*sump[q[h]]+G(i);

43         while(h<t&&V(q[t],i)*(sump[q[t-1]]-sump[q[t]])<=V(q[t-1],q[t])*(sump[q[t]]-sump[i])) t--;

44         q[++t]=i;

45     }

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

47 }

48 

49 int main()

50 {

51     read();

52     go();

53     return 0;

54 }

 

 

你可能感兴趣的:(2007)