Poj Square 需要二刷 *DFS剪枝问题,非常重要

基本思想:

崩溃了,主要还是有两个问题:

1.存在剪枝问题,不剪枝会超时;

2.DFS写法的问题,感觉OJ里特别喜欢通过返回true false,来进行多循环的一次递归解决所有问题;

bool dfs(int n,int index,int value,int num) {
    if (num == 3)
        return true;
    for (int i = index; i < n; i++) {
        if (!vis[i]) {
            vis[i] = true;
            if (vec[i] + value == cnt) {
                if (dfs(n, 0, 0, num+1))
                    return true;
            }
            else if (vec[i] + value < cnt) {
                if (dfs(n, i+1, vec[i] + value, num))
                    return true;
            }
            vis[i] = false;
        }
    }
    return false;
}

 以上述代码为例,通过一次递归进入来获得所有的结果;

首先进行排序,保证从大的选起,从而不会发生小的选完大的无法适配的情况,这个自己当时也看出来了;

总的来说,是通过三次迭代进行计算,每次迭代通过递归遍历来找到满足条件的情况;

当时卡在了如何把这三次迭代连起来,自己采用for循环循环三次,还是超时了;

大佬的代码是通过当第一次情况满足的时候,直接递归套入新的一层迭代,并且由于vis数组不改变,所以可以看作再前一次的基础上进行继续寻找;

 其次,利用num来进行迭代次数监控,当num=3的时候,直接开头就return true;

整体后续的判断是否正确都可以通过return来反应到第一层,所以就会得知是否能够找到成功的情况。可以看作是前一道DFS的升级版,需要分层;

关键点:

剪枝问题;

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

const int maxn = 22;
bool vis[maxn];
vector<int>vec;
int cnt;//边长

void init(int n) {
    fill(vis, vis + n, false);
    vec.resize(n);
    //correct = 0;
    cnt = 0;
}

bool cmp(int a, int b) {
    return a > b;
}

bool dfs(int n,int index,int value,int num) {
    if (num == 3)
        return true;
    for (int i = index; i < n; i++) {
        if (!vis[i]) {
            vis[i] = true;
            if (vec[i] + value == cnt) {
                if (dfs(n, 0, 0, num+1))
                    return true;
            }
            else if (vec[i] + value < cnt) {
                if (dfs(n, i+1, vec[i] + value, num))
                    return true;
            }
            vis[i] = false;
        }
    }
    return false;
}

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int m;
        cin >> m;
        init(m);
        for (int i = 0; i < m; i++) {
            cin >> vec[i];
            cnt += vec[i];
        }
        if (cnt % 4 != 0) {
            cout << "no" << endl;
            continue;
        }
        cnt /= 4;
        sort(vec.begin(), vec.end(), cmp);
        if (vec[0] > cnt) {
            cout << "no" << endl;
            continue;
        }
        //dfs(n, 0, vec[0]);
        if (dfs(m,0,0,0))
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/songlinxuan/p/12446189.html