1 条题解

  • 0
    @ 2025-8-24 22:34:23

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Kawaii_qiuw
    你看那峭壁之上生一枝红花_

    搬运于2025-08-24 22:34:23,当前版本为作者最后更新于2025-01-04 11:28:38,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目大意

    Alice 和 Bob 又在玩游戏。

    在他们面前有 nn 块石头排成一行,石头有红和蓝两种颜色。

    Alice 先手,每次每人从两端选择一端取出一块石头,谁先取出 kk 块红色石头谁输掉。

    假设 Alice 和 Bob 都是绝顶聪明的,求出最后谁获胜。

    解题思路

    记忆化搜索。

    fl,r,kf_{l,r,k} 表示现在区间是 [l,r][l,r],现在先手有 kk 块红石子的胜负。

    sum1sum1sum2sum2 分别为前缀和、后缀和。

    那么对方手上的石子数就为 sum1l1+sum2r+1ksum1_{l - 1} + sum2_{r + 1} - k

    每次特判 sum1l1+sum2r+1ksum1_{l - 1} + sum2_{r + 1} - k 有没有大于 KK

    valsum1l1+sum2r+1val \to sum1_{l − 1} + sum2_{r + 1}

    那么答案就是 f1,n,0f_{1,n,0}

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int n , k , b[351] , a[351] , sum1[351] , sum2[351] , dp[351][351][351];
    char c;
    int dfs (int l , int r, int s) {
        if (sum1[l - 1] + sum2[r + 1] - s == k) return dp[l][r][s] = 2;
        if (dp[l][r][s]) return dp[l][r][s];
        int ans1 , ans2;
        ans1 = dfs (l + 1 , r , sum1[l - 1] + sum2[r + 1] - s);
        ans2 = dfs (l , r - 1 , sum1[l - 1] + sum2[r + 1] - s);
        return dp[l][r][s] = (ans1 == 1 || ans2 == 1) ? 2 : 1;
    }
    int main () {
        scanf ("%d%d" , &n , &k);
        for (int i = 1 ; i <= n ; i ++) {
            c = getchar ();
            while (c != 'C' && c != 'P') c = getchar ();
            a[i] = (c == 'C');
        }
        for (int i = 1 ; i <= n ; i ++) sum1[i] = sum1[i - 1] + a[i];
        for (int i = n ; i >= 1 ; i --) sum2[i] = sum2[i + 1] + a[i];
        puts (dfs (1 , n , 0) == 2 ? "DA" : "NE");
        return 0;
    }
    
    

    AC 记录。

    完结撒花。

    • 1

    信息

    ID
    7277
    时间
    1000ms
    内存
    512MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者