description
【問題背景】
小k攢足了路費來到了教主所在的宮殿門前,但是當小k要進去的時候,卻發現了要與教主守護者進行乙個特殊的遊戲,只有取到了最大值才能進去orz教主……
【問題描述】
守護者拿出被劃分為n個格仔的乙個圓環,每個格仔上都有乙個正整數,並且定義兩個格仔的距離為兩個格仔之間的格仔數的最小值。環的圓心處固定了乙個指標,一開始指向了圓環上的某乙個格仔,你可以取下指標所指的那個格仔裡的數以及與這個格仔距離小於k的格仔的數,取乙個數的代價即這個數的值。指標是可以轉動的,每次轉動可以將指標由乙個格仔轉向其相鄰的格仔,且代價為圓環上還剩下的數的最大值。
現在對於給定的圓環和k,求將所有數取完所有數的最小代價。
input
輸入檔案的第1行有兩個正整數n和k,描述了圓環上的格仔數與取數的範圍。
第2行有n個正整數,按順時針方向描述了圓環上每個格仔上的數,且指標一開始指向了第1個數字所在的格仔。
所有整數之間用乙個空格隔開,且不超過10000。
output
輸出檔案僅包括1個整數,為取完所有數的最小代價。
sample input
6 1sample output4 1 2 3 1 3
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...