其他分享
首页 > 其他分享> > 【2019台北】J(状压bitset) & E(构造)

【2019台北】J(状压bitset) & E(构造)

作者:互联网

## 2019icpc台北

J

应该是一个很板的状压&bitset题目(但是之前没用过bitset直接T飞)

bitset写法

bitset<505> ss[20];
void solve(){
    int n,m; char s;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            cin >> s;
            if(s == '1') ss[i][j] = 1;
            else ss[i][j] = 0;
        }
    }

    int ans = 1000;
    for(int i=0;i<1<<m;i++){
        int num=0; bitset<505> tmp;
        for(int j=0;j<m;j++){
            if(i&(1<<j)){
                num++;
                if (num > ans ) break;
                tmp |= ss[j];
            }
        }
        if(tmp.count() == n) ans =min(num,ans);
    }
    if(ans==1000)cout<<-1<<endl;
    else cout<<ans<<endl;
}

玄学优化写法
枚举状态之后按位枚举,当前位找到一组在这位有1的就直接看下一位

void solve(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++) {
        for(int j=0;j<n;j++){
            scanf(" %c",&s);
            if(s=='1')
                ve[j].push_back(i);
        }
    }
    //sort(ve.begin(),ve.end(),cmp);
    int ans = 1000;
    for(int i=0;i<1<<m;i++){
        int num=0;
        for(int j=0;j<m;j++){
            if((1<<j)&i) ++num;
            if(num>ans)break;
        }

        if(num>ans)continue; //优化1

        for(int l =0;l<n;l++){ //优化2
            for(auto j : ve[l]){
                if((1<<j)&i) { st[l] = 1;break; }
            }
        }
        bool f=0;
        for(int l =0;l<n;l++){
            if(!st[l]) f=1;
            st[l]=0;
        }
        if(!f) ans =num;
    }
    if(ans==1000)cout<<-1<<endl;
    else printf("%d\n",ans);
    for(int i=0;i<n;i++) ve[i].clear();
}

E

构造
\(1999*(1998+k)-1998*(1999+k) = k\)
第一个数为-1 , 然后将k分到其他1998个数里面

标签:tmp,int,1998,状压,ss,2019,bitset,ans
来源: https://www.cnblogs.com/muscletear/p/15813664.html