HDU 6199 dp

題意:

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6199
AB兩個人玩遊戲,n個數,從左到右依次選取。第一個人可以選擇1個或者2個數,假設某一輪一個人選擇了k個數,那麼下一輪另一個人就要選擇k個或者k+1個數,如果剩下的數字不夠就不能選擇,遊戲終止。此時比較A-B的大小,問兩個人都採取最優策略,都儘可能讓自己所獲得的數的總和大,最後A-B的最大值是多少。


思路:

真的菜,網絡賽時候有正確思路,結果細節沒搞清楚,最後愣是沒調出來。
dp[i][j][0/1]表示當前這一輪是0(A)或1(B)選擇數字,還剩下j個數,馬上將要選擇i個數的A-B的最大值。然後從後往前倒着推,最後答案就是max(dp[1][n][0], dp[2][n][0])。
狀態轉移方程爲:
dp[i][j][0] = min(dp[i][j-i][1], dp[i+1][j-i][1])+val;
dp[i][j][1] = max(dp[i][j-i][0], dp[i+1][j-i][0])+val;
其中,val爲選擇的i個數的總和,這裏有一點一定要注意,0對應min,而1對應max,不能搞反。因爲這是從後往前倒推的,當前是0面對的一定是之前的1所留下來對1最好的局面,也就是min。
噁心的爆內存,要改成滾動數組。
還要注意很多細節問題,詳見代碼。


代碼:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 2e9 + 1;
const int MAXN = 2e4 + 10;

int a[MAXN], sum[MAXN], dp[2][MAXN][2];

int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        if (n == 1) {
            printf("%d\n", a[1]);
            continue;
        }
        for (int i = 199; i >= 1; i--) {
            for (int j = i; j <= n; j++) {
                int l = n - j, r = n - j + i;
                if (j - i < i) {
                    dp[i % 2][j][0] = sum[r] - sum[l];
                    dp[i % 2][j][1] = -(sum[r] - sum[l]);
                }
                else {
                    dp[i % 2][j][0] = dp[i % 2][j - i][1] + sum[r] - sum[l];
                    dp[i % 2][j][1] = dp[i % 2][j - i][0] - (sum[r] - sum[l]);
                    if (i + 1 <= 199 && j - i >= i + 1) {
                        dp[i % 2][j][0] = min(dp[i % 2][j][0], dp[(i + 1) % 2][j - i][1] + sum[r] - sum[l]);
                        dp[i % 2][j][1] = max(dp[i % 2][j][1], dp[(i + 1) % 2][j - i][0] - (sum[r] - sum[l]));
                    }
                }
            }
        }
        int ans = max(dp[0][n][0], dp[1][n][0]);
        printf("%d\n", ans);
    }
    return 0;
}
發佈了255 篇原創文章 · 獲贊 29 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章