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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P6047-丝之割【斜率优化,dp】

發(fā)布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P6047-丝之割【斜率优化,dp】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

然而絲之鴿還是沒有出


正題

題目鏈接:https://www.luogu.com.cn/problem/P6047


題目大意

兩個平行的線,上面連接著若干條弦,第iii條連接上方的xix_ixi?個下方的yiy_iyi?。
然后每次可以選擇一個位置(i,j)(i,j)(i,j),可以切斷任何位于位置(u,v)(u,v)(u,v)的弦僅當滿足條件(u>i,v<j)(u>i,v<j)(u>i,v<j),消耗代價為ai?bja_i*b_jai??bj?。

求切斷所有線的最小代價。


解題思路

如果我們將下面那條線翻轉(zhuǎn)過來,我們就有條件(u>i,v>j)(u>i,v>j)(u>i,v>j),我們將弦看成坐標的話,我們可以發(fā)現(xiàn)其實就是每次選擇一個點然后將右下角的點都去掉。

所以就有以下優(yōu)化

  • 如果一個弦代表的點在其他弦代表點的右下角,那么該點不影響結(jié)果??梢匀サ?/li>
  • 如果一個點的代價比他右上角的其中一個點的代價高,那么必定選那個點更優(yōu)。所以我們可以對于aaabbb都取一個前綴minminmin
  • 做完以下優(yōu)化后,對于弦我們可以求到xxx遞增,yyy遞減的序列。轉(zhuǎn)換到之后就是axa_xax?遞減,byb_yby?遞增的序列,可以進行dpdpdp
    fi=min{fj,fj+axj+1byi}f_i=min\{f_j,f_j+a_{x_j+1}b_{y_i}\}fi?=min{fj?,fj?+axj?+1?byi??}
    考慮斜率優(yōu)化
    fi=fj+axj+1byif_i=f_j+a_{x_j+1}b_{y_i}fi?=fj?+axj?+1?byi??
    轉(zhuǎn)換成函數(shù)
    fj=?axj+1byi+fif_j=-a_{x_j+1}b_{y_i}+f_ifj?=?axj?+1?byi??+fi?

    斜率為?byi-b_{y_i}?byi??要求截距最小,維護下凸殼(斜率遞增)。

    然后因為都是單調(diào)的,可以用單調(diào)隊列維護。


    codecodecode

    #include<cstdio> #include<algorithm> #define ll long long using namespace std; const ll N=3e5+10; struct node{ll x,y; }a[N]; ll n,m,q[N]; double x[N],y[N],f[N]; bool cmp(node x,node y) {return (x.x==y.x)?(x.y<y.y):(x.x<y.x);} double slope(ll i,ll j){if(a[i+1].x==a[j+1].x)return 1e18;return (f[i]-f[j])/(a[j+1].x-a[i+1].x); } int main() {scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lf",&x[i]);for(ll i=n;i>=1;i--)scanf("%lf",&y[i]);x[0]=y[0]=1e18;for(ll i=1;i<=n;i++)x[i]=min(x[i],x[i-1]),y[i]=min(y[i],y[i-1]);for(ll i=1;i<=m;i++)scanf("%lld%lld",&a[i].x,&a[i].y),a[i].y=n-a[i].y+1;sort(a+1,a+1+m,cmp);ll p=0;a[0].y=2147483647/3;for(ll i=1;i<=m;i++)if(a[i].y<a[p].y)a[++p]=a[i];m=p;ll l=1,r=1;for(ll i=1;i<=m;i++)a[i].x=x[a[i].x-1],a[i].y=y[a[i].y-1];for(ll i=1;i<=m;i++){while(l<r&&slope(q[l],q[l+1])<=a[i].y)l++;ll pos=q[l];f[i]=f[pos]+a[pos+1].x*a[i].y;while(l<r&&slope(q[r-1],q[r])>slope(q[r],i))r--;q[++r]=i;}printf("%.0lf",f[m]); }

    總結(jié)

    以上是生活随笔為你收集整理的P6047-丝之割【斜率优化,dp】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。