P2392 kkksc03考前临时抱佛脚

 

昨天晚上看了题目没思路。 早上上课回来之后想着就直接根据题目搞一个左脑一个右脑,然后两边分别加时间取最大暴搜,结果T了九个,这是代码。

#include <iostream>
using namespace std;

int tAns, ans;
int s[5], array[30];
bool is_use[30];

void preprocessing() {
    for (int i = 1; i <= 4; i++) {
        cin >> s[i];
    }
}

void dfs(int step, int left, int right, int n) {
    int ans = max (left, right);
    if (ans >= tAns) {
        return;
    }
    if (step == n) {
        tAns = min(ans, tAns);
    }
    for (int i = 1; i <= n; i++) {
        if (!is_use[i]) {
            is_use[i] = true;
            dfs(step + 1, left + array[i], right, n);
            dfs(step + 1, left, right + array[i], n);
            is_use[i] = false;
        }
    }
}

void solve() {
    for (int i = 1; i <= 4; i++) {
        tAns = 0x7fffffff;
        for (int j = 1; j <= s[i]; j++) {
            cin >> array[j];
        }
        dfs(0, 0, 0, s[i]);
        ans += tAns;
    }
    cout << ans;
}

int main() {
    preprocessing();
    solve();
    return 0;
}

尝试了各种剪枝,还是过不了一点。

最后发现问题是这个循环。


    for (int i = 1; i <= n; i++) {
        if (!is_use[i]) {
            is_use[i] = true;
            dfs(step + 1, left + array[i], right, n);
            dfs(step + 1, left, right + array[i], n);
            is_use[i] = false;
        }
    }

实际上无脑公式化套用了前面几道搜索题的做法,类似套模板,没有真的理解这道题的本质。

这道题left和right两个分别加上时间的做法任务就是试完n个,而不需要每一次都从1到n试。

具体的,对于每一个状态,只需从left和right中选择一个进入

对于这样一个问题,只要按顺序一个个试下去,每个都试left和right即可。

所以这段代码把循环去了就AC了。

#include <iostream>

using namespace std;

int tAns, ans;
int s[5], array[30];

void preprocessing() {
    for (int i = 1; i <= 4; i++) {
        cin >> s[i];
    }
}

void dfs(int step, int left, int right, int n) {
    int ans = max (left, right);
    if (ans >= tAns) {
        return;
    }
    if (step == n) {
        tAns = ans;
        return;
    }
    dfs(step + 1, left + array[step + 1], right, n);
    dfs(step + 1, left, right + array[step + 1], n);
    return;
}

void solve() {
    for (int i = 1; i <= 4; i++) {
        for (int j = 1; j <= s[i]; j++) {
            cin >> array[j];
        }
        tAns = 0x7fffffff;
        dfs(0, 0, 0, s[i]);
        ans += tAns;
    }
    cout << ans;
}

int main() {
    preprocessing();
    solve();
    return 0;
}
posted @ 2023-10-10 12:42  加固文明幻景  阅读(21)  评论(0编辑  收藏  举报  来源