洛谷 動態規劃 單調佇列 P1714 切蛋糕

2022-05-26 23:15:13 字數 1688 閱讀 6721

【題目描述:】

今天是小z的生日,同學們為他帶來了一塊蛋糕。這塊蛋糕是乙個長方體,被用不同色彩分成了n個相同的小塊,每小塊都有對應的幸運值。

小z作為壽星,自然希望吃到的第一塊蛋糕的幸運值總和最大,但小z最多又只能吃m小塊(m≤n)的蛋糕。

吃東西自然就不想思考了,於是小z把這個任務扔給了學oi的你,請你幫他從這n小塊中找出連續的k塊蛋糕(k≤m),使得其上的幸運值最大。

【輸入格式:】

輸入檔案cake.in的第一行是兩個整數n,m。分別代表共有n小塊蛋糕,小z最多只能吃m小塊。

第二行用空格隔開的n個整數,第i個整數pi代表第i小塊蛋糕的幸運值。

【輸出格式:】

輸出檔案cake.out只有一行,乙個整數,為小z能夠得到的最大幸運值。

[演算法分析:]

如果是想f[i]跟前面的某個狀態有關就錯了,這不是琪露諾,可以吃完m個之後繼續吃

而是只能吃m小塊蛋糕,所以dp方程應該是這個樣子的:$$f[i] = max^ a_} + a_i$$

\[1≤i≤n

\]而求\(\sum a_\)的過程可以使用字首和優化,這樣時間複雜度便從\(o(n^3)\)優化到了\(o(n^2)\)

未優化的普通dp**:

//求max 

int maxn = 1 << 31;

int e = min(i, m) - 1;

for(int j=1; j<=e; ++j)

maxn = max(maxn, sum[i-1] - sum[i-j-1]);

if(maxn > maxn + a[i]) f[i-1] = maxn;

f[i] = maxn + a[i];

而對於\(n≤500000\)的資料顯然\(n^2\)的複雜度是不達到要求的,

優化了求和,還可以優化求最大值的過程

線段樹優化的複雜度是\(o(nlog_2n)\)顯然是可以過的,但還可以用單調佇列優化到\(o(n)\).

將字首和存入單調佇列,每一次都找到當前點到隊首點的區間和,保證隊首點值最小就能使得幸運值最大,所以佇列中的元素應是從小到大排。

當隊首的位置加上\(m\)之後還是無法到大點\(i\)時,就把隊首\(pop\)掉.

單調佇列中使用int型別表示元素的位置,要訪問元素的值的話就是sum[q.front()]就好.

\([code:]\)

#include#include#includeusing namespace std;

const int maxn = 500000 + 1;

int n, m;

int a[maxn];

int sum[maxn], f[maxn];

struct node ;

dequeq;

inline int read()

while(ch>='0' && ch<='9')

x=(x<<3)+(x<<1)+ch-48, ch=getchar();

return x * f;

}int main()

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

int ans = 1 << 31;

for(int i=1; i<=n; ++i) ans = max(ans, f[i]);

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

}

洛谷 P1714 切蛋糕 單調佇列

今天是小z的生日,同學們為他帶來了一塊蛋糕。這塊蛋糕是乙個長方體,被用不同色彩分成了n個相同的小塊,每小塊都有對應的幸運值。小z作為壽星,自然希望吃到的第一塊蛋糕的幸運值總和最大,但小z最多又只能吃m小塊 m n 的蛋糕。吃東西自然就不想思考了,於是小z把這個任務扔給了學oi的你,請你幫他從這n小塊...

洛谷P1714 切蛋糕 題解 單調佇列

題目大意 給你乙個大小為 n 的陣列,求滿足區間元素個數 le m 的連續子串行和的最大值。解題思路 假設陣列中第 i 個元素為 a i 我可以定義 sum i 表示前 i 個數之和 sum i sum i 1 a i 則,以 a i 結尾的最大連續子串行和為 sum i min sum j 我們可...

P1714 切蛋糕 單調佇列

p1714 切蛋糕 單調佇列 gyro永不抽風 最後更新 2020年09月20日 18 09 許可協議 今天是小z的生日,同學們為他帶來了一塊蛋糕。這塊蛋糕是乙個長方體,被用不同色彩分成了n個相同的小塊,每小塊都有對應的幸運值。小z作為壽星,自然希望吃到的第一塊蛋糕的幸運值總和最大,但小z最多又只能...