考慮 爲砍掉第 棵樹的最小代價,因爲 ,所以目的是求
考慮計算 。因爲 單調遞減,所以砍掉編號 的樹之後,就不會再回來管 ,而是向 奮起直追。這一點似乎很多題解裡並沒有考慮。
所以 只會由 的 來轉移,所以我們考慮列舉 ,此時 。於是得到了一個 的樸素
考慮優化決策時間複雜度。對於前置決策 且,當前位置 ,該從哪裏轉移過來。對於選擇 的條件爲
移項得到:
顯然的斜率優化,單調佇列維護即可。
LL a[MAXN], b[MAXN], dp[MAXN];
deque<LL> Q;
DB Getk(LL i,LL j)
{
return (dp[i] - dp[j] + 0.0) / (b[j] - b[i]);
}
int main()
{
LL n;
read( n );
for (Int i = 1; i <= n; ++ i)
read( a[i] );
for (Int i = 1; i <= n; ++ i)
read( b[i] );
Q.push_front( 1 );
for (Int i = 2; i <= n; ++ i)
{
while (Q.size() > 1)
{
LL t1 = Q.front();
Q.pop_front();
LL t2 = Q.front();
Q.pop_front();
if (Getk(t1, t2) > a[i])
{
Q.push_front( t2 );
Q.push_front( t1 );
break;
}
else Q.push_front( t2 );
}
LL j = Q.front();
dp[i] = dp[j] + b[j] * a[i];
while (Q.size() > 1)
{
LL t1 = Q.back();
Q.pop_back();
LL t2 = Q.back();
Q.pop_back();
if (Getk(t1, i) > Getk(t2, t1))
{
Q.push_back( t2 );
Q.push_back( t1 );
break;
}
else Q.push_back( t2 );
}
Q.push_back( i );
}
printf("%lld", dp[n]);
return 0;
}