1010: [HNOI2008]玩具装箱toy
2016-01-29 12:56
323 查看
原来的DP式子:
设f[i]为前i个玩具装箱的总费用
f[i] = min{ f[j]+ (i-(j+1)+s[i]-s[j]-l)^2 }
展开得
令g[i]=i+s[i]
h[j]=j+1+s[j]+l
f[i] = min{ f[j]+(g[i]-h[j]) ^2} = min{f[j] + h[j] ^ 2 - 2 * g[i] *h[j] } + g[i] ^ 2
设j1<j2
如果决策j2 比j1优
f[j1]+ h[j1]^ 2 - 2* g[i] *h[j1]>f[j2]+ h[j2]^ 2 - 2* g[i] *h[j2]
(h[j2]-h[j1])*2*g[i]>f[j2]+h[j2]^2-f[j1]-h[j1]^2
slope(j1,j2)<2*g[i]
g[i]单调递增
f[j]+h[j]^2单调递增
同时,如果在a,b,c中b最优,那么slope(a,b)<2*g[i] and slope(b,c)>2*g[i] ==>slope(b,c)>slope(a,b)斜率单调递增
用单调队列维护下凸壳(斜率是正的,即上下增减性相同)
平方要注意long long
还有 slope(j1,j2)虽然数值上等于slope(j2,j1) 但是放在不等式中如果改变j1, j2位置,实际上不等号是要改变的,所以slope是唯一确定的
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define MAXN 50010
int n,l,top,tail,j;
int q[MAXN],a[MAXN];
long long s[MAXN],f[MAXN];
long long F(int x)
{
return f[x]+s[x]*s[x]+2*l*s[x];
}
double slope(int a,int b)
{
return (F(a)-F(b))/(s[a]-s[b]);
}
int main()
{
scanf("%d%d", &n, &l);
l++;
for (int i=1;i<=n;i++)
scanf("%d", &a[i]);
for (int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
for (int i=1;i<=n;i++) s[i]+=i;
top=1;tail=1;
q[top]=0;
for (int i=1;i<=n;i++)
{
while (top<tail && slope(q[top],q[top+1])<=2*s[i]) top++;
j=q[top];
f[i]=f[j]+(s[i]-s[j]-l)*(s[i]-s[j]-l);
while (tail>top && slope(q[tail],i)<=slope(q[tail-1],q[tail])) tail--;
q[++tail]=i;
}
printf("%lld", f
);
}
设f[i]为前i个玩具装箱的总费用
f[i] = min{ f[j]+ (i-(j+1)+s[i]-s[j]-l)^2 }
展开得
令g[i]=i+s[i]
h[j]=j+1+s[j]+l
f[i] = min{ f[j]+(g[i]-h[j]) ^2} = min{f[j] + h[j] ^ 2 - 2 * g[i] *h[j] } + g[i] ^ 2
设j1<j2
如果决策j2 比j1优
f[j1]+ h[j1]^ 2 - 2* g[i] *h[j1]>f[j2]+ h[j2]^ 2 - 2* g[i] *h[j2]
(h[j2]-h[j1])*2*g[i]>f[j2]+h[j2]^2-f[j1]-h[j1]^2
slope(j1,j2)<2*g[i]
g[i]单调递增
f[j]+h[j]^2单调递增
同时,如果在a,b,c中b最优,那么slope(a,b)<2*g[i] and slope(b,c)>2*g[i] ==>slope(b,c)>slope(a,b)斜率单调递增
用单调队列维护下凸壳(斜率是正的,即上下增减性相同)
平方要注意long long
还有 slope(j1,j2)虽然数值上等于slope(j2,j1) 但是放在不等式中如果改变j1, j2位置,实际上不等号是要改变的,所以slope是唯一确定的
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define MAXN 50010
int n,l,top,tail,j;
int q[MAXN],a[MAXN];
long long s[MAXN],f[MAXN];
long long F(int x)
{
return f[x]+s[x]*s[x]+2*l*s[x];
}
double slope(int a,int b)
{
return (F(a)-F(b))/(s[a]-s[b]);
}
int main()
{
scanf("%d%d", &n, &l);
l++;
for (int i=1;i<=n;i++)
scanf("%d", &a[i]);
for (int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
for (int i=1;i<=n;i++) s[i]+=i;
top=1;tail=1;
q[top]=0;
for (int i=1;i<=n;i++)
{
while (top<tail && slope(q[top],q[top+1])<=2*s[i]) top++;
j=q[top];
f[i]=f[j]+(s[i]-s[j]-l)*(s[i]-s[j]-l);
while (tail>top && slope(q[tail],i)<=slope(q[tail-1],q[tail])) tail--;
q[++tail]=i;
}
printf("%lld", f
);
}
相关文章推荐
- [BZOJ1096][ZJOI2007][DP][斜率优化]仓库建设
- [BZOJ1492][NOI2007][斜率优化][动态凸包][DP][分治]货币兑换cash
- HDU 3045
- 【bzoj1010】【斜率优化】【HNOI2008】玩具装箱toy
- (解题报告) Uva 1616 Caravan Robbers (商队抢劫者)(上凸包+队列+结构体)
- [BZOJ1010][HNOI2008]玩具装箱toy(斜率优化)
- hdu 3507 斜率优化dp入门
- 2015湖南省队集训DAY4——hoodle
- DP:斜率优化 Slope optimization
- 斜率优化DP 【pascal】
- 斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解
- 斜率优化专题2——bzoj 1010 [HNOI2008]玩具装箱toy 题解
- 斜率优化专题3——bzoj 3156 防御准备 题解
- 斜率优化专题4——bzoj 1911: [Apio2010] 特别行动队 题解
- 斜率优化专题5——bzoj 1096 [ZJOI2007]仓库建设 题解
- BZOJ 1010: [HNOI2008]玩具装箱toy
- 2015.08.10总结
- 1D1D动规优化初步
- hdu 1300 Pearls(DP)
- Average UVA - 1451