日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ1010 [HNOI2008]玩具装箱toy 动态规划 斜率优化

發布時間:2024/1/17 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ1010 [HNOI2008]玩具装箱toy 动态规划 斜率优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接http://www.cnblogs.com/zhouzhendong/p/8687797.html

題目傳送門 - BZOJ1010

題意

  一個數列$C$,然后把這個數列劃分成若干段。

  對于數列$C$的某一段,是從$i$~$j$的,那么就會產生$(i-j+(\sum_{k=i}^j C_k)-L)^2$的花費。

  一種劃分方式的花費就是劃分出來的每一段產生的花費和。

  求所有不同的劃分方式所產生的總花費中最小花費為多少。

  序列長度$\leq 5\times 10^4$。

題解

  看著好像斜率優化啊。

  恩對斜率優化,我們來推式子。

  記

  $dp_i$表示數列$C$的長度為$i$的前綴序列的最小花費。

  $sum_i=\sum_{j=1}^{i}C_j$

  $s_i=sum_i+i$

  于是我們很容易得到:

  $$dp_i=min\{dp_j+(s_i-s_j-1-L)^2\}(0\leq j<i)$$

  然后我們推一推式子。

  $$dp_j+(s_i-s_j-1-L)^2\\=dp_j+s_j^2+2(L+1)s_j-2s_is_j+si^2-2(L+1)s_i+(L+1)^2$$

  假設$j>k$,且選$j$優于選擇$k$,則:

  $$dp_j+s_j^2+2(L+1)s_j-2s_is_j+si^2-2(L+1)s_i+(L+1)^2<dp_k+s_k^2+2(L+1)s_k-2s_is_k+si^2-2(L+1)s_i+(L+1)^2$$

  $$\Longrightarrow?dp_j+s_j^2+2(L+1)s_j-2s_is_j<dp_k+s_k^2+2(L+1)s_k-2s_is_k$$

  令

  $$x_i=s_i$$

  $$y_i=dp_i+s_i^2+2(L+1)s_j$$

  $$dp_j+s_j^2+2(L+1)s_j-2s_is_j<dp_k+s_k^2+2(L+1)s_k-2s_is_k$$

  $$\Longrightarrow y_j-2s_ix_j<y_k-2s_ix_k$$

  $$\Longrightarrow \frac{y_j-y_k}{x_j-x_k}<2s_i$$

  注意由于開始限制了$j>k$所以$x_j-x_k>0$,所以最后兩邊同時相除不等式仍然成立。

  設

  $$g_{i,j}=\frac{y_i-y_j}{x_i-x_j}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i>j)$$

  則上式可以表示為$g_{j,k}<2s_i$

  我們來發掘以下$g_{j,k}$的性質。

  1. 當$g_{j,k}\leq 2s_i$時,由于隨著$i$變大,$2s_i$也變大,所以顯然從$k$轉移是永遠不會比$j$好的,所以我們可以把$k$扔掉。

  2. 當$g_{i,j}\leq g_{j,k}$時,從$i$或者$k$轉移至少有一個不比$j$差,所以可以把$j$扔掉。為什么??

    若$g_{i,j}\leq 2s_i$,顯然$j$要被扔掉,根據第一個性質。

    若$g_{i,j}>2s_i$,則$g_{j,k}>2s_i$,那么顯然$j$比$k$差,也得被扔掉。

  于是我們可以用一個單調隊列來維護斜率的單調性。

  具體的:

  當情況1發生的時候讓隊首出隊。

  在進隊的時候,如果發生情況2,那么先讓隊尾出隊,然后再進隊。

  為了避免精度問題,我們可以把$x_i-x_j$乘上來。

代碼

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=50005; int n,q[N],head=1,tail=0; LL L,s[N],dp[N],x[N],y[N]; int main(){scanf("%d%lld",&n,&L);for (int i=1;i<=n;i++)scanf("%lld",&s[i]),s[i]+=s[i-1]+1;q[++tail]=0;for (int i=1;i<=n;i++){int j=q[head+1],k=q[head];while (tail-head>0&&y[j]-y[k]<=2LL*s[i]*(x[j]-x[k]))head++,j=q[head+1],k=q[head];j=k;dp[i]=dp[j]+(s[i]-s[j]-L-1)*(s[i]-s[j]-L-1);x[i]=s[i];y[i]=dp[i]+s[i]*s[i]+2LL*(L+1)*s[i];j=q[tail],k=q[tail-1];while (tail-head>0&&(y[i]-y[j])*(x[j]-x[k])<=(y[j]-y[k])*(x[i]-x[j]))tail--,j=q[tail],k=q[tail-1];q[++tail]=i;}printf("%lld",dp[n]);return 0; }

  

轉載于:https://www.cnblogs.com/zhouzhendong/p/BZOJ1010.html

總結

以上是生活随笔為你收集整理的BZOJ1010 [HNOI2008]玩具装箱toy 动态规划 斜率优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。