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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[POJ 3709] K-Anonymous Sequence(斜率优化dp / 动态维护凸包)

發(fā)布時(shí)間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [POJ 3709] K-Anonymous Sequence(斜率优化dp / 动态维护凸包) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

K-Anonymous Sequence

看了兩年前自己的博客,真的好青澀,連 markdown 都不太會(huì)用。

確實(shí)觀賞感不是很好。

學(xué)習(xí)真的是慢慢積累的過(guò)程,以前感覺(jué)理解很困難的事,隨著知識(shí)的增長(zhǎng),現(xiàn)在都基本悟了。

problem

POJ3709

solution

設(shè) f(i):f(i):f(i): 考慮到前 iii 個(gè)數(shù),并在 iii 個(gè)數(shù)劃分的最小花費(fèi)。

可以直接列出狀態(tài)轉(zhuǎn)移,枚舉前一段的位置 jjj ,則 [j+1,i][j+1,i][j+1,i] 要求相同,且長(zhǎng)度要夠長(zhǎng)。

f(i)=min?{f(j)+sum(i)?sum(j)+a[j+1]?(i?j)}(j≤i?m)f(i)=\min\Big\{f(j)+sum(i)-sum(j)+a[j+1]*(i-j)\Big\}(j\le i-m)f(i)=min{f(j)+sum(i)?sum(j)+a[j+1]?(i?j)}(ji?m)

其中 sum(i):sum(i):sum(i):iii 個(gè)數(shù)的和,即前綴和。

注意到題目給的性質(zhì) a[i]a[i]a[i] 是單增的。

考慮兩個(gè)合法轉(zhuǎn)移點(diǎn) j<kj<kj<k ,且 jjj 不優(yōu)于 kkk

即滿足:f(j)+sum(i)?sum(j)+a[j+1]?(i?j)≥f(k)+sum(i)?sum(k)+a[k+1]?(i?k)f(j)+sum(i)-sum(j)+a[j+1]*(i-j)\ge f(k)+sum(i)-sum(k)+a[k+1]*(i-k)f(j)+sum(i)?sum(j)+a[j+1]?(i?j)f(k)+sum(i)?sum(k)+a[k+1]?(i?k)

化簡(jiǎn)得:f(j)?sum(j)?a[j+1]?j?f(k)+sum(k)+a[k+1]?k≥i?(a[j+1]?a[k+1])f(j)-sum(j)-a[j+1]*j-f(k)+sum(k)+a[k+1]*k\ge i*\big(a[j+1]-a[k+1]\big)f(j)?sum(j)?a[j+1]?j?f(k)+sum(k)+a[k+1]?ki?(a[j+1]?a[k+1])

一般來(lái)說(shuō),斜率優(yōu)化是把 iii 的系數(shù)簡(jiǎn)化為 111 的分式形式。但是有些題目可能存在“平臺(tái)”,即系數(shù)算出來(lái)為 000

除法分母不能是 000,所以為了防止程序死掉,乘法形式才是最好選擇。

但是因?yàn)椴坏仁降拇嬖诒仨氁?aaa 的單調(diào)性,否則中途的決策點(diǎn)選擇有不等式的變號(hào),就不是斜率優(yōu)化了。

李超樹才是我們的紅太陽(yáng)!

單調(diào)隊(duì)列存儲(chǔ)合法轉(zhuǎn)移點(diǎn),每次取最優(yōu)的隊(duì)首轉(zhuǎn)移。

對(duì)于隊(duì)首的維護(hù)是非常簡(jiǎn)單的。

但斜率優(yōu)化難以理解的問(wèn)題就在隊(duì)尾的維護(hù),即常說(shuō)的凸包維護(hù)。

網(wǎng)上很多就直接上凸包圖像,然后從直線斜率角度入手,這里不贅述。

以此題為例,用語(yǔ)言化的最優(yōu)點(diǎn)選擇來(lái)嘗試闡釋斜率問(wèn)題。

一般會(huì)有,令 Y(j,k)=f(j)?sum(j)?a[j+1]?j?f(k)+sum(k)+a[k+1]?kX(j,k)=a[j+1]?a[k+1]Y(j,k)=f(j)-sum(j)-a[j+1]*j-f(k)+sum(k)+a[k+1]*k\quad X(j,k)=a[j+1]-a[k+1]Y(j,k)=f(j)?sum(j)?a[j+1]?j?f(k)+sum(k)+a[k+1]?kX(j,k)=a[j+1]?a[k+1]

如果只考慮兩個(gè)選擇點(diǎn) (x,y)(x,y)(x,y),顯然當(dāng) iii 增大后,不等式可能存在反向的問(wèn)題,即 xxx 不一定就永遠(yuǎn)差于 yyy。【現(xiàn)在是要考慮 iii 后面點(diǎn)的轉(zhuǎn)移,iii 點(diǎn)也是轉(zhuǎn)移點(diǎn)】

所以是考慮三個(gè)點(diǎn) (x,y,z),x<y<z(x,y,z),x<y<z(x,y,z),x<y<z【這對(duì)應(yīng)著計(jì)算 iii 后,iii 與凸包上的最后一個(gè)點(diǎn)形成的直線,以及凸包最后兩個(gè)點(diǎn)形成的直線,兩個(gè)直線的維護(hù)】

因?yàn)楸绢}是最小值,所以當(dāng) Y(x,y)X(x,y)≥Y(y,z)X(y,z)?Y(x,y)?X(y,z)≥Y(y,z)?X(x,y)\frac{Y(x,y)}{X(x,y)}\ge \frac{Y(y,z)}{X(y,z)}\Rightarrow Y(x,y)·X(y,z)\ge Y(y,z)·X(x,y)X(x,y)Y(x,y)?X(y,z)Y(y,z)??Y(x,y)?X(y,z)Y(y,z)?X(x,y) 時(shí),去掉 yyy。【維護(hù)凸包】

接下來(lái)解釋為什么??

回到上面式子去,因?yàn)?aaa 是單增,所以 j<k?X(j,k)<0j<k\Rightarrow X(j,k)<0j<k?X(j,k)<0 。即 Y(j,k)X(j,k)≤i\frac{Y(j,k)}{X(j,k)}\le iX(j,k)Y(j,k)?i,證明 jjj 不優(yōu)于 kkk,且注意到 Y(j,k)X(j,k)\frac{Y(j,k)}{X(j,k)}X(j,k)Y(j,k)? 是一個(gè)常數(shù),與枚舉點(diǎn) iii 無(wú)關(guān)。

現(xiàn)在回到這里,對(duì)于某個(gè) iii,如果 Y(y,z)X(y,z)≥i\frac{Y(y,z)}{X(y,z)}\ge iX(y,z)Y(y,z)?i 那么一定有 Y(x,y)X(x,y)≥i\frac{Y(x,y)}{X(x,y)}\ge iX(x,y)Y(x,y)?i

即,如果 yyy 優(yōu)于 zzz,那么 xxx 一定也優(yōu)于 yyy,那就沒(méi)有 yyy 什么事了。【對(duì)應(yīng)的上凸包維護(hù),即斜率逐漸遞減】

code

#include <cstdio> using namespace std; #define int long long #define maxn 500005 int T, n, m; int a[maxn], q[maxn], f[maxn], sum[maxn];int Y( int j, int k ) {return f[j] - sum[j] + j * a[j + 1] - f[k] + sum[k] - k * a[k + 1]; }int X( int j, int k ) {return a[j + 1] - a[k + 1]; }signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld", &n, &m );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] ), sum[i] = sum[i - 1] + a[i];int head = 1, tail = 0; q[++ tail] = 0;for( int i = 1;i <= n;i ++ ) {while( head < tail and Y( q[head], q[head + 1] ) >= i * X( q[head], q[head + 1] ) ) head ++;int j = q[head];f[i] = f[j] + sum[i] - sum[j] - a[j + 1] * ( i - j );int k = i - m + 1;if( k >= m ) {while( head < tail and Y( q[tail - 1], q[tail] ) * X( q[tail], k ) >= Y( q[tail], k ) * X( q[tail - 1], q[tail] ) )tail --;q[++ tail] = k;}}printf( "%lld\n", f[n] );}return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的[POJ 3709] K-Anonymous Sequence(斜率优化dp / 动态维护凸包)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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