一、题目
二、解法
状态定义我都没有想到(好菜啊),我们的目标是砍掉最后一颗树,所以定义
d
p
[
i
]
dp[i]
dp[i]为砍掉第
i
i
i棵树的最小花费,转移枚举之前砍掉的一棵树:
d
p
[
i
]
=
d
p
[
j
]
+
a
[
i
]
×
b
[
j
]
dp[i]=dp[j]+a[i]\times b[j]
dp[i]=dp[j]+a[i]×b[j]然后就是斜率优化的板子,不想多讲。。。
#include <cstdio>
#define int long long
const int M = 100005;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,h,t,a[M],b[M],q[M],dp[M];
double g(int x,int y)
{
return 1.0*(dp[x]-dp[y])/(b[y]-b[x]);
}
signed main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=n;i++)
b[i]=read();
q[0]=1;
for(int i=2;i<=n;i++)
{
while(h<t && g(q[h+1],q[h])<a[i]) h++;
dp[i]=dp[q[h]]+b[q[h]]*a[i];
while(h<t && g(i,q[t])<=g(q[t],q[t-1])) t--;
q[++t]=i;
}
printf("%lld\n",dp[n]);
}