區間dp jzoj1397 圓環取數

2021-08-21 06:38:40 字數 1725 閱讀 6558

description

【問題背景】

小k攢足了路費來到了教主所在的宮殿門前,但是當小k要進去的時候,卻發現了要與教主守護者進行乙個特殊的遊戲,只有取到了最大值才能進去orz教主……

【問題描述】

守護者拿出被劃分為n個格仔的乙個圓環,每個格仔上都有乙個正整數,並且定義兩個格仔的距離為兩個格仔之間的格仔數的最小值。環的圓心處固定了乙個指標,一開始指向了圓環上的某乙個格仔,你可以取下指標所指的那個格仔裡的數以及與這個格仔距離小於k的格仔的數,取乙個數的代價即這個數的值。指標是可以轉動的,每次轉動可以將指標由乙個格仔轉向其相鄰的格仔,且代價為圓環上還剩下的數的最大值。

現在對於給定的圓環和k,求將所有數取完所有數的最小代價。

input

輸入檔案的第1行有兩個正整數n和k,描述了圓環上的格仔數與取數的範圍。

第2行有n個正整數,按順時針方向描述了圓環上每個格仔上的數,且指標一開始指向了第1個數字所在的格仔。

所有整數之間用乙個空格隔開,且不超過10000。

output

輸出檔案僅包括1個整數,為取完所有數的最小代價。

sample input

6 1

4 1 2 3 1 3

sample output
21
【樣例說明】

如上圖所示,第一步不轉動指標,取走4、3兩個數,代價為7;

第2步指標順時針轉動2格,圓環上最大數為3,代價為6,取走1、2、3三個數,代價為6;

第3步指標順時針轉動1格,代價為1,取走剩下的乙個數1,代價為1;

最小代價為7+6+6+1+1=21。

【資料規模】

對於20%的資料,n≤10,k≤3;

對於40%的資料,n≤100,k≤10;

對於60%的資料,n≤500,k≤20;

對於100%的資料,n≤2000,k≤500;

反正我這種蒟蒻是沒想出來的了。

因為每個數我們都是要取的,所以問題就變成求取完所有數的最小代價。

設f[i][j][0/1]表示向左轉i格,向右轉j格指標在左(i格)或指標在右(j格)的最小代價。

預處理出區間最大值,t[i][j]表示區間i到j(包括i,j)的最大值。

動態轉移方程為 

f[i][j][0]=min(f[i-1][j][0]+mx,f[i-1][j][1]+mx*(i+j));

f[i][j][1]=min(f[i][j-1][1]+mx,f[i][j-1][0]+mx*(i+j));

其中mx表示剩下的最大值。

code

#include#include#include#define inf 0x3f3f3f

using namespace std;

int n,k,ans,lll;

int a[2000+200],f[2000+20][2000+20][2];

int t[2000+200][2000+200];

int main()

for(int i=1;i<=n;i++)

}ans=inf;

printf("%d\n",ans);

for(int i=0;i<=n;i++)

for(int j=0;j<=n-i;j++)

else

if(j>0)

else

if(i+j==n)

}printf("%d",ans+lll);

}

1 區間選點 區間問題

區間問題一般都需要對區間進行排序,對左端點排序,或對右端點排序,或雙關鍵字排序 然後需要 證明這樣的選法選出來的點數一定是符合答案的,且是選點最少的 首先按照這個方法來選的話,每乙個區間上一定選了乙個點,所以這種選法是一種合法的方案 然後這道題的最優解是指所有合法方案中的選點最少的,所以 所以ans...

1 判斷數字所在區間

1 0 找區間 輸入兩個閉區間,然後輸入n個數字,依次輸出每個數字所在的區間有幾個。例如 1 5 區間 1,5 3 6 區間 3,6 31 47輸出 120 1 1 不僅要輸出每個數字所在的區間,還要輸出它所在的區間是幾號區間。剛才的輸出應該變為 1 12 1 2 0 1 自己寫的 include ...

分塊 區間眾數(金牌導航 分塊 1)

給出乙個數列,和若干詢問,每個詢問讓你求乙個區間內的眾數 6 3 1 2 3 2 1 2 1 5 3 6 1 51 2 11 n 4 1 04,1 m 5 104 1 a i 10 91 leqslant n leqslant 4 times 10 4,1 leqslant m leqslant 5...