80分代码求调qwq
查看原帖
80分代码求调qwq
94746
安安宝贝尺寸楼主2024/7/23 02:33

第八第九,还有subtask三个点WA 样例+讨论版hack数据全过,代码下面另附的两组数据也过了

#include <cmath>
#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
using namespace std;

struct brick {
    int score;
    bool contains_bullet;
};

//滚动数组,在线算法
int main() {
    size_t n, m, k;
    cin >> n >> m >> k;

    vector<array<int, 2> > prev_dp(k + 1); //之前的dp结果, prev_dp[i][j]代表截至上一行为止,用i颗子弹能获取的最大分数(其中j == 1代表返还一个子弹,j == 0代表不返还)
    vector mp(m, vector<brick>(n));

    //倒序输入
    for (size_t i = n - 1; ; --i) {
        for (size_t j = 0; j < m; ++j) {
            char c;
            cin >> mp[j][i].score >> c;
            mp[j][i].contains_bullet = c == 'Y';
        }
        if (!i)
            break;
    }

    for (size_t i = 0; i < n; ++i) {
        vector<brick> cur{move(mp[i])};

        //便输入边算,在线算法,输入完了结果也同步算出来了
        vector<array<int, 2> > cur_bu_to_score({{0, 0}, {0, 0}});
        //cur_bu_to_score[i][j]代表当前弹道有index的子弹时能够获得的最大分数(一弹一段表),其中j == 1时要求返还子弹(若不可能则用0表示)
        cur_bu_to_score.reserve(m + 2); //合法的子弹数量是从0到k,一共k+1项,而下面的算法会溢出一项,所以额外+1

        for (auto [s, c]: cur) {
            auto &b = cur_bu_to_score.back();
            b[0] += s;
            if (c) {
                b[1] = b[0];
            } else
                cur_bu_to_score.push_back({b[0], 0});
        }
        if (!cur_bu_to_score.back()[1]) //若最后一项不给子弹,上面的算法会多插入一项,这里弹一下
            cur_bu_to_score.pop_back();

        // fixme  最后一块砖里有子弹的情况

        vector<array<int, 2> > cur_dp(k + 1);
        //用j遍历每一个可能的(在所有列中一共的)可用的子弹数量
        for (size_t j = 0; j <= k; ++j) {
            //l代表分给新的一列多少子弹
            for (size_t l = 0; l <= min(j, cur_bu_to_score.size() - 1); ++l) {
                //生成新一列的dp结果
                //这里只拿到l个子弹,而可用的子弹数为j,意味着前面已经用掉j-l颗子弹了
                cur_dp[j][0] = max({
                    true                                                            ? cur_dp[j][0]                                  : 0,
                    true                                                            ? prev_dp[j - l][0] + cur_bu_to_score[l][0]     : 0,
                    prev_dp[j - l][1] && l < min(j, cur_bu_to_score.size() - 1) ? prev_dp[j - l][1] + cur_bu_to_score[l + 1][0] : 0,
                    cur_bu_to_score[l][1] && l                                      ? prev_dp[j - l + 1][0] + cur_bu_to_score[l][1] : 0,
                });
                cur_dp[j][1] = max({
                    true                                                                                     ? cur_dp[j][1]                                  : 0,
                    prev_dp[j - l][1]                                                                        ? prev_dp[j - l][1] + cur_bu_to_score[l][0]     : 0,
                    cur_bu_to_score[l][1]                                                                    ? prev_dp[j - l][0] + cur_bu_to_score[l][1]     : 0,
                    prev_dp[j - l][1] && cur_bu_to_score[l][1] && l < min(j, cur_bu_to_score.size() - 1) ? prev_dp[j - l][1] + cur_bu_to_score[l + 1][1] : 0,
                    prev_dp[j - l][1] && cur_bu_to_score[l][1] && l                                          ? prev_dp[j - l + 1][1] + cur_bu_to_score[l][1] : 0,
                });
            }
        }

        prev_dp = move(cur_dp); //滚动数组,节省空间
    }

    cout << prev_dp[k][0];
}

/*
3 3 3
1 N 1 N 1 N
1 N 1 Y 1 Y
3 Y 3 N 1 Y


1 2 1
1 N 1 N
 */

2024/7/23 02:33
加载中...