單調隊列最佳化動態規劃

來源:互聯網
上載者:User

標籤:位置   div   ges   window   notice   disco   ssis   typedef   cut   

先來看這道題:

USACO 2011 Open Gold Mowing the Lawn 修剪草坪

After winning the annual town competition for best lawn a year ago,
Farmer John has grown lazy; he has not mowed the lawn since then
and thus his lawn has become unruly. However, the competition is
once again coming soon, and FJ would like to get his lawn into
tiptop shape so that he can claim the title.

Unfortunately, FJ has realized that his lawn is so unkempt that he
will need to get some of his N (1 <= N <= 100,000) cows, who are
lined up in a row and conveniently numbered 1..N, to help him. Some
cows are more efficient than others at mowing the lawn; cow i has
efficiency E_i (0 <= E_i <= 1,000,000,000).

FJ has noticed that cows near each other in line often know each
other well; he has also discovered that if he chooses more than K
(1 <= K <= N) consecutive (adjacent) cows to help him, they will
ignore the lawn and start a party instead. Thus, FJ needs you to
assist him: determine the largest total cow efficiency FJ can obtain
without choosing more than K consecutive cows.

顯然這是一道動態規劃題目,我們先簡化題目。題意是這樣的:

FJ 有 N(1≤N≤100000) 只排成一排的奶牛,編號為 1...N。每隻奶牛的效率是不同的, 奶牛 i 的效率為 Ei(0≤Ei≤1000000000)。靠近的奶牛們很熟悉,因此,如果 FJ 安排超過 K(1≤K≤N) 只連續的奶牛,那麼,這些奶牛就會罷工去開派對。現在 FJ 需要你協助計算可以得到的最大效率。

如果我們用 dp[i] 來表示前i頭奶牛的最大效率,那麼我們可以寫出這樣的轉移方程:

dp[i]=max?{dp[j?1]+sum[i]?sum[j]} (i?K≤j≤i)

這樣的轉移方程的時間複雜度是O(NK),觀察這道題的資料量,相當於O(N^2),顯然是不行的。

仔細觀察,實際上對於 dp[i] 來說,我們需要找到一個決策 j(i?K≤j≤i) 使得 dp[j?1]?sum[j] 最大化。再看,不難發現,i和j都是單調遞增的,這讓我們聯想到以前做過的Sliding Windows,窗戶的兩邊也是單調的對吧。所以這道題我們其實也可以用單調隊列來最佳化。我們用這個單調隊列來維護這個下標j的位置。

 1 #include <stdio.h> 2  3 typedef long long LL; 4 const int maxn = 100010; 5 LL dp[maxn], sum[maxn]; 6 int que[maxn], E[maxn]; 7 int head, tail; 8 LL max(LL a, LL b) { 9     return a > b? a : b;10 }11 void add(int j) {12     while (head < tail && dp[j - 1] - sum[j] >= (que[tail - 1] > 0 ? dp[que[tail - 1] - 1] : 0) - sum[que[tail - 1]]) {13         --tail;14     }15     que[tail++] = j;16 }17 void del(int j) {18     if (head < tail && que[head] == j) {19         ++head;20     }21 }22 int main() {23     int n, k;24     scanf("%d %d", &n, &k);25     sum[0] = 0;26     for (int i = 1; i <= n; ++i) {27         scanf("%d", &E[i]);28         sum[i] = sum[i - 1] + E[i];29     }30     dp[0] = 0;31     que[tail++] = 0;32     for (int i = 1; i <= n; ++i) {33         add(i);34         del(i - k - 1);35         int j = que[head];36         dp[i] = (j > 0 ? dp[j - 1] : 0) + sum[i] - sum[j];37     }38     LL ans = max(dp[n], dp[n - 1]);39     printf("%lld\n", ans);40     return 0;41 }

 

單調隊列最佳化動態規劃

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.