• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

yongchaoD

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

popcorn(dfs,二进制记录答案)

题目来源:https://atcoder.jp/contests/abc358/tasks/abc358_c
//
题意:m种爆米花,n个店铺,每个店铺有一个m长的字符串,如果第j个字符为o,则意味着i摊位出售口味j的爆米花。问最少多少次的店铺购买,就能购买到所有种类的爆米花。
//
思路:
dfs搜索啊,把每个字符串转化为01串,然后每位进行异或运算(位运算没写出来,后面可以优化下代码,该题解是直接模拟的),然后每次新访问一个店铺后刷新状态,然后cheak(判断是否所有的爆米花都购买了)下,输出最小值cnt就可以了。
//

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=19;
vector<string>mp(19);
vector<int>vis(N,0);
vector<string>a(N);
int n,m,Min=N;

bool cheak(string s){
    for(int i=0;i<m;i++){
        if(s[i]=='0') return false;
    }
    return true;
}

void dfs(int x,string s,int cnt){//从第x个店铺开始,s:当前购买爆米花状态,在cnt个店铺买了
    if(cheak(s)){
        Min=min(Min,cnt);
        return;
    }

    for(int i=x+1;i<=n;i++){
        string t=s;
        for(int j=0;j<m;j++){
            if(s[j]=='1'&&a[i][j]=='1'){
                t[j]='1';
            }
            else if(s[j]=='1'&&a[i][j]=='0'){
                t[j]='1';
            }
            else if(s[j]=='0'&&a[i][j]=='1'){
                t[j]='1';
            }
            else if(s[j]=='0'&&a[i][j]=='0'){
                t[j]='0';
            }
        }
        vis[i]=1;
        cnt++;
        dfs(i,t,cnt);
        cnt--;
        vis[i]=0;
    }
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>mp[i];
        for(int t=m-1;t>=0;t--){//转为2进制
            if(mp[i][t]=='o'){
                mp[i][t]='1';
            }
            else{
                mp[i][t]='0';
            }
        }
        a[i]=mp[i];
    }

    //dfs()找到最少次数求得2^m
    for(int i=1;i<=n;i++){
        dfs(i,a[i],1);
    }
    cout<<Min<<endl;
    return 0;
}

posted on 2024-07-15 16:07  yongchaoD  阅读(29)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3