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

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

生活随笔

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

编程问答

Vijos1451圆环取数[环形DP|区间DP]

發(fā)布時(shí)間:2025/7/14 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vijos1451圆环取数[环形DP|区间DP] 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

小K攢足了路費(fèi)來(lái)到了教主所在的宮殿門(mén)前,但是當(dāng)小K要進(jìn)去的時(shí)候,卻發(fā)現(xiàn)了要與教主守護(hù)者進(jìn)行一個(gè)特殊的游戲,只有取到了最大值才能進(jìn)去Orz教主……

描述

守護(hù)者拿出被劃分為n個(gè)格子的一個(gè)圓環(huán),每個(gè)格子上都有一個(gè)正整數(shù),并且定義兩個(gè)格子的距離為兩個(gè)格子之間的格子數(shù)的最小值。環(huán)的圓心處固定了一個(gè)指針,一開(kāi)始指向了圓環(huán)上的某一個(gè)格子,你可以取下指針?biāo)傅哪莻€(gè)格子里的數(shù)以及與這個(gè)格子距離不大于k的格子的數(shù),取一個(gè)數(shù)的代價(jià)即這個(gè)數(shù)的值。指針是可以轉(zhuǎn)動(dòng)的,每次轉(zhuǎn)動(dòng)可以將指針由一個(gè)格子轉(zhuǎn)向其相鄰的格子,且代價(jià)為圓環(huán)上還剩下的數(shù)的最大值。

現(xiàn)在對(duì)于給定的圓環(huán)和k,求將所有數(shù)取完所有數(shù)的最小代價(jià)。

格式

輸入格式

輸入文件cirque.in的第1行有兩個(gè)正整數(shù)n和k,描述了圓環(huán)上的格子數(shù)與取數(shù)的范圍。

第2行有n個(gè)正整數(shù),按順時(shí)針?lè)较蛎枋隽藞A環(huán)上每個(gè)格子上的數(shù),且指針一開(kāi)始指向了第1個(gè)數(shù)字所在的格子。

所有整數(shù)之間用一個(gè)空格隔開(kāi),且不超過(guò)10000。

輸出格式

輸出文件cirque.out僅包括1個(gè)整數(shù),為取完所有數(shù)的最小代價(jià)。

樣例1

樣例輸入1[復(fù)制]

6 1 4 1 2 3 1 3

樣例輸出1[復(fù)制]

21

限制

對(duì)于20%的數(shù)據(jù),n≤10,k≤3;
對(duì)于40%的數(shù)據(jù),n≤100,k≤10;
對(duì)于60%的數(shù)據(jù),n≤500,k≤20;
對(duì)于100%的數(shù)據(jù),n≤2000,k≤500;

時(shí)限1s。

提示

如上圖所示,第一步不轉(zhuǎn)動(dòng)指針,取走4、3兩個(gè)數(shù),代價(jià)為7;
第2步指針順時(shí)針轉(zhuǎn)動(dòng)2格,圓環(huán)上最大數(shù)為3,代價(jià)為6,取走1、2、3兩個(gè)數(shù),代價(jià)為6;
第3步指針順時(shí)針轉(zhuǎn)動(dòng)1格,代價(jià)為1,取走剩下的一個(gè)數(shù)1,代價(jià)為1;
最小代價(jià)為7+6+6+1+1=21。

--------------------------------------------------

該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死該死

取數(shù)的代價(jià)一定,只考慮轉(zhuǎn)移

貪心發(fā)現(xiàn)能取就取一定不丟最優(yōu)解,從1開(kāi)始,剩下的一定一直是一段區(qū)間

然后我就開(kāi)始做死了f[i][j][0/1]表示剩下[i,j]這段區(qū)間,0表示指針在i-k-1處,1表示指針在j+k+1處,調(diào)了三四個(gè)小時(shí)也沒(méi)調(diào)出來(lái)

看人家的題解,i和j都來(lái)表示左/右“取了幾個(gè)數(shù)”

然而我發(fā)現(xiàn),他們的意思更準(zhǔn)確的是左右的指針跳到了哪里

轉(zhuǎn)移如代碼,至于哪個(gè)>0否則INF,好像是簡(jiǎn)化了一下情況,不會(huì)丟失

該死該死該死

#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef long long ll; const int N=2005,INF=1e9; int n,k,a[N],f[N][N][2],ans=INF,sum=0; int mx[N][16]; void initRMQ(int n){for(int i=1;i<=n;i++) mx[i][0]=a[i];for(int j=1;j<=12;j++)for(int i=1;i+(1<<j)-1<=n;i++)mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]); } int RMQ(int l,int r){if(l>r) return 0;int k=log(r-l+1)/log(2);return max(mx[l][k],mx[r-(1<<k)+1][k]); } void dp(){f[1][n][0]=f[1][n][1]=0;for(int i=0;i<=n;i++)for(int j=0;j<=n-i;j++){if(i==0&&j==0) continue;int m=RMQ(i+k+1,n-k-j);if(i>0) f[i][j][0]=min(f[i-1][j][0]+m,f[i-1][j][1]+m*(i+j));else f[i][j][0]=INF;m=RMQ(i+k+2,n-k-j+1);if(j>0) f[i][j][1]=min(f[i][j-1][1]+m,f[i][j-1][0]+m*(i+j));else f[i][j][1]=INF;} } int main(int argc, const char * argv[]) {scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];initRMQ(n);dp();for(int i=1;i<=n;i++) ans=min(ans,min(f[i][n-i][1],f[i][n-i][0]));cout<<ans+sum;return 0; }

?

?

總結(jié)

以上是生活随笔為你收集整理的Vijos1451圆环取数[环形DP|区间DP]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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