solution-p1391

dfs

思路

这道题肯定要用DFS。如果直接暴力枚举,只有40pts。

那么,该如何优化呢?

考虑使用贪心。我们发现,当第一行确定下来时,后面几行就会受限,有唯一解!!

所以,我们只需要枚举第一行。$2^{18}$ 还是可以接受的。

还有一个小细节需要注意。

总时间复杂度 $O(2^n \cdot n^2)$

代码

#include<bits/stdc++.h>
using namespace std;// 0 girl 1 boy
bool f[200][200];
int n;
int cnt2[200][200];
bool f2[200][200];//143213
int ans = 2147483647;

void print(){
    for(int i = 1; i <= n; i++){
        cout<<f[1][i]<<' ';
    }cout<<endl;
}

void solve(int h){
    int cnt = h;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(i == 1){
                cnt2[i][j] = f2[i][j-1] + f2[i][j+1];
                continue;
            }
            cnt2[i][j] = f2[i-1][j] + f2[i][j-1];
            if(cnt2[i-1][j] % 2){
                if(f2[i][j] == 0){
                    cnt++;
                }
                f2[i][j] = 1;
                cnt2[i][j-1]++;
            }else{
                if(f2[i][j] == 1){
                    memset(cnt2, 0, sizeof(cnt2));
                    return ;
                }
                f2[i][j] = 0;
            }
        }
    }
    bool flag = true;
    for(int i = 1; i <= n; i++){
        if(cnt2[n][i] % 2){
            flag = false;
            break;
        }
    }
    if(flag){
        ans = min(ans, cnt);
    }
    memset(cnt2, 0, sizeof(cnt2));
}

void dfs(int x, int cnt){
    if(x > n){
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                f2[i][j] = f[i][j];
            }
        }
        solve(cnt);
        return ;
    }
    if(f[1][x] == 0){
        f[1][x] = 0;
        dfs(x+1, cnt);
        f[1][x] = 1;
        dfs(x+1, cnt+1);
        f[1][x] = 0;
        return ;
    }else{
        dfs(x+1, cnt);
    }
}

int main(){
    cin>>n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin>>f[i][j];
        }
    }
    dfs(1, 0);
    if(ans == 2147483647)   cout<<-1<<endl;
    else cout<<ans<<endl;
//  cout<<ans<<endl;
    return 0;
}

后续

做完这道题可以尝试一下P1764,都是一种套路的题。

posted @ 2022-01-22 19:50  WRuperD  阅读(0)  评论(0编辑  收藏  举报  来源

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

这是一条自定义内容

这是一条自定义内容