1. 程式人生 > >BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏寶箱:區間dp 博弈【兩種表示方法】【壓維】

BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏寶箱:區間dp 博弈【兩種表示方法】【壓維】

space print 而且 problem 所有 php 一條直線 題解 bzoj

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=2101

題意:

  共有n枚金幣,第i枚金幣的價值是w[i]。

  把金幣排成一條直線,Bessie和Bonny輪流取金幣,看誰取到的錢最多。

  Bessie先取,每次只能取一枚金幣,而且只能選擇取直線兩頭的金幣,不能取走中間的金幣。當所有金幣取完之後,遊戲就結束了。

  Bessie和Bonny都是非常聰明的,她們會采用最好的辦法讓自己取到的金幣最多。

  請幫助Bessie計算一下,她能拿到多少錢?

題解:

  區間dp共有兩種表示狀態的方法:

    (1)dp[i][j]:表示區間[i,j]的答案。

      一般轉移為:dp[i][j] = best(dp[i+1][j], dp[i][j-1])

    (2)dp[i][j]:左端點為i,區間長度為j。

      一般轉移為:dp[i][j] = best(dp[i][j-1], dp[i+1][j-1])

  顯然,第二種是可以壓維的。因為dp[i][j]只與dp[...][j-1]有關。

  在此題中,第一種表示會炸空間,所以只能用第二種。

  表示狀態:

    dp[i][j] = max wealth

    i:起點為i

    j:區間長度為j

    表示對於當前區間,先手的最大獲利。

  找出答案:

    ans = dp[1][n]

    表示整個區間。

  如何轉移:

    對於一個區間,這個區間內的價值總和是一定的。

    那麽如果要讓自己獲利更大,就是要讓對方接下來的獲利最小。

    自己的獲利 = 區間價值總和 - 對方獲利

    即:dp[i][j] = sum(i,i+j-1) - min(dp[i][j-1], dp[i+1][j-1])

  邊界條件:

    dp[i][1] = w[i]

    只能拿走剩下的一個硬幣。

  優化:

    壓維。

    前綴和。

AC Code:

 1 // state expression:
 2 // dp[i][j] = max wealth
3 // i: start pos 4 // j: len of present section 5 // 6 // find the answer: 7 // dp[1][n] 8 // 9 // transferring: 10 // dp[i][j] = sum(i,i+j-1) - min(dp[i][j-1], dp[i+1][j-1]) 11 // 12 // boundary: 13 // dp[i][1] = w[i] 14 #include <iostream> 15 #include <stdio.h> 16 #include <string.h> 17 #define MAX_N 5005 18 19 using namespace std; 20 21 int n; 22 int w[MAX_N]; 23 int dp[MAX_N]; 24 int sum[MAX_N]; 25 26 void read() 27 { 28 cin>>n; 29 for(int i=1;i<=n;i++) 30 { 31 cin>>w[i]; 32 } 33 } 34 35 void cal_sum() 36 { 37 sum[0]=0; 38 for(int i=1;i<=n;i++) 39 { 40 sum[i]=sum[i-1]+w[i]; 41 } 42 } 43 44 void solve() 45 { 46 cal_sum(); 47 for(int j=1;j<=n;j++) 48 { 49 for(int i=1;i<=n;i++) 50 { 51 if(j==1) dp[i]=w[i]; 52 else dp[i]=sum[i+j-1]-sum[i-1]-min(dp[i],dp[i+1]); 53 } 54 } 55 } 56 57 void print() 58 { 59 cout<<dp[1]<<endl; 60 } 61 62 int main() 63 { 64 read(); 65 solve(); 66 print(); 67 }

BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏寶箱:區間dp 博弈【兩種表示方法】【壓維】