【BZOJ 3675】[Apio2014]序列分割
2017-10-09 16:54
281 查看
【链接】 链接
【题意】
在这里输入题意
【题解】
模拟一下样例。
会发现。切的顺序不影响最后的答案。
只要切点确定了。
答案就确定了。
则设f[i][j]表示前i段,第i段保留到j的最大值。
\(f[i][j] = max(f[i-1][x] + (s[j]-s[x])*(s
-s[j]))\)
\(s[i] = a[1] + a[2] +...+a[i]\)
然后还是考虑x < y 且y优于x
balabala最后能得到
\(\frac{f[i-1][y]-f[-1][x]}{s[y]-s[x]}>s
-s[j]\)
而s
-s[j]是单调递减的;
这就能加一个斜率优化了。
注意这里是>s
-s[j]才y更优。
则队列的出入队和经典的斜率优化条件相反。
最后输出f[k+1]
就好;
要用滚动数组。不然会MLE.
【错的次数】
在这里输入错的次数
【反思】
在这里输入反思
【代码】
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5,K = 200; int n,k,h,t,dl[N+10]; ll a[N+10],f[2][N+10],s[N+10]; double ju(int i,int x,int y) { double fenzi = f[(i-1)&1][y] - f[(i-1)&1][x]; double fenmu = s[y] - s[x]; if (s[y]==s[x]) return 2e9; return fenzi/fenmu; } int main() { //freopen("F:\\rush.txt","r",stdin); scanf("%d%d",&n,&k); for (int i = 1;i <= n;i++) scanf("%lld",&a[i]); for (int i = 1;i <= n;i++) s[i] = s[i-1] + a[i]; for (int i = 1;i <= k + 1;i++) { memset(f[i&1],0,sizeof f[i&1]); h = t = 1; dl[1] = 0; for (int j = 1;j <= n;j++) { while (h < t && ju(i,dl[h],dl[h+1]) > s -s[j]) h++; int x = dl[h]; f[i&1][j] = max(f[i&1][j],f[(i-1)&1][x] + (s[j]-s[x])*(s -s[j])); while (h < t && ju(i,dl[t-1],dl[t]) < ju(i,dl[t],j)) t--; dl[++t] = j; } } printf("%lld\n",f[(k+1)&1] ); return 0; }
相关文章推荐
- bzoj3675: [Apio2014]序列分割【斜率优化dp】
- BZOJ3675 [Apio2014]序列分割 【斜率优化dp】
- [BZOJ3675][Apio2014]序列分割(斜率优化dp)
- [Bzoj3675][Apio2014]序列分割(斜率优化)
- [BZOJ3675][Apio2014]序列分割-斜率优化-动态规划
- 【斜率优化】bzoj3675-[Apio2014]序列分割&&Uoj104
- bzoj3675: [Apio2014]序列分割
- [BZOJ3675][Apio2014]序列分割
- BZOJ 3675: [Apio2014]序列分割
- bzoj3675: [Apio2014]序列分割
- [BZOJ 3675][APIO 2014]序列分割(斜率优化DP)
- BZOJ 3675 APIO2014 序列分割 斜率优化DP
- BZOJ3675 [APIO2014]序列分割(斜率优化模板)
- 【斜率DP】BZOJ 3675:[Apio2014]序列分割
- BZOJ 3675: [Apio2014]序列分割
- 动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割
- [BZOJ3675][Apio2014]序列分割(斜率优化DP)
- bzoj 3675: [Apio2014]序列分割
- [bzoj 3675--Apio2014]序列分割
- bzoj3675 [APIO2014] 序列分割(斜率优化)