【解题思路】
设s[i]=i+∑c[j](j∈[1,n]∩N)
易得转移方程f[i]=min{f[j]+(s[i]-s[j]-L-1)2},朴素算法复杂度O(n2)。
考虑斜率优化:记T[i]=s[i]+L+1
若成立f[j]+(s[i]-s[j]-L-1)2<=f[k]+(s[i]-s[k]-L-1)2(j<k)
<=>f[j]+(s[i]-T[j])2<=f[k]+(s[i]-T[k])2
<=>(f[j]+T[j]2)-(f[k]+T[k]2)<=2*s[i]*(T[j]-T[k])
<=>((f[j]+T[j]2)-(f[k]+T[k]2))/(T[j]-T[k])<=2*s[i]
则设P[i](T[i],f[i]+T[i]2),维护单调队列(按相邻两点斜率降序排序),当队列要加入i时,P[j]和P[k]的共存条件是(P[j]-P[k])斜率不超过2*s[i],整个单调队列呈一个下凸壳。时间复杂度O(n)。
【参考代码】
1 #include <cctype> 2 #include <cstdio> 3 #define REP(I,start,end) for(int I=(start);I<=(end);I++) 4 #define PER(I,start,end) for(int I=(start);I>=(end);I--) 5 typedef unsigned short US; 6 typedef unsigned long UL; 7 typedef long long LL; 8 typedef unsigned long long ULL; 9 typedef long double LD; 10 inline int space() 11 { 12 return putchar(' '); 13 } 14 inline int enter() 15 { 16 return putchar(' '); 17 } 18 inline bool eoln(char ptr) 19 { 20 return ptr==' '; 21 } 22 inline bool eof(char ptr) 23 { 24 return ptr=='