problem 4 聰明伶俐的香穗子
香穗子遇到難題了.
題目是這樣的,乙個序列上有n個整數,現在你要取m個,且這m個數的任意兩個不能相隔的太近,否則這樣會太醜,現在問你最大能得到多大的和
輸入:
第一行三個數n,m,k,分別表示n個數,取m個,且m個中的任意兩個位置差要大於等於k
接下來一行,有n個整數,表示序列上的每個數
輸出:
最大和sample input
4 2 2
3 4 -5 1
sample output
資料範圍:
n<=10000,m<=100,m<=n
答案保正小於 maxlongint
看起來很像是單調佇列,但是完全用不著,單調佇列怎麼說也要難除錯一些。
f[i][j] = max(f[k][j-1] + a[i]),i-k>=k。因此就限定了k的取值區間,但是因為已經說過與最後一選沒有關係,因此我們可以轉換一下狀態表示,表示「前」i個數選j個。
因此f[i][j]=max(f[i-1][j] , f[i-k][j-1]+a[i])。
用單調佇列也不是沒法做。
f[i][j] = max(f[k][j-1] + a[i]),i-k>=k。
觀察發現,只與上一行的j左邊的區域有關,因此我們可以讓動規和單調佇列的維護剛好非同步一行的位置,即用上一行的j左邊的f值來維護單調佇列。
但是要注意每一行對應乙個單調佇列,所以列舉i的時候一定要將單調佇列清空,一開始就因為這個除錯了很久。
#include #include #define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
long a[10010];
long f[10010][101];
long getint()
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}int main()
} printf("%ld",f[n][m]);
return 0;
}
#include #include #include #define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
long getint()
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}long a[10010];
long que[10010];
long f[10010][2];
int main()
long l = 0;
long r = 0;
long ths = 0;
long pre = 1;
for (long i=1;i-0x3f3f3f3f)
{while (l
動規遞推 聰明伶俐的香穗子
聰明伶俐的香穗子 香穗子遇到難題了.題目是這樣的,乙個序列上有n個整數,現在你要取m個,且這m個數的任意兩個不能相隔的太近,否則這樣會太醜,現在問你最大能得到多大的和 輸入 第一行三個數n,m,k,分別表示n個數,取m個,且m個中的任意兩個位置差要大於等於k 接下來一行,有n個整數,表示序列上的每個...
動態規劃 聰明的kk
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 聰明的 kk 可移動 沙丘 變戲法 的靈感源於其獨特而雄偉的自然景觀 富於傳奇色彩的險峻沙丘。巨集偉的結構 可迴圈的建材,與大自然相得益彰。環繞一周,發現它正是從沙丘那不斷變換的形態中汲取靈感的。外形逼真到無論從哪個角度去觀察,...
聰明的kk 動態規劃
時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 聰明的 kk 可移動 沙丘 變戲法 的靈感源於其獨特而雄偉的自然景觀 富於傳奇色彩的險峻沙丘。巨集偉的結構 可迴圈的建材,與大自然相得益彰。環繞一周,發現它正是從沙丘那不斷變換的形態中汲取靈感的。外形逼真到無論從哪個角度去觀察,...