二分+暴力状压+桶——cf1288D

/*
二分bk,所有比bk大的数设置为1,比bk小的数设置为0
然后得到一个n*m的01矩阵,每行a的状态用s[i]表示,问题转换成判是否存在s[i]|s[j]=(1<<m)-1
    再开一个flag[i]统计是否出现过状态i 
    然后暴力枚举是否存在这样的s[i]|s[j]=(1<<m)-1 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005

int a[N][10],n,m,s[N],flag[1<<10];
int ans1,ans2;

int judge(int mid){
    memset(s,0,sizeof s);
    memset(flag,-1,sizeof flag);
    
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++)
            if(a[i][j]>=mid)
                s[i]|=(1<<j);
        flag[s[i]]=i;
    }
    
    for(int i=0;i<(1<<m);i++)if(flag[i]!=-1){
        for(int j=0;j<(1<<m);j++)if(flag[j]!=-1)
            if((i|j) == (1<<m)-1){
                ans1=flag[i]+1,ans2=flag[j]+1;return 1;
            }
    }
    
    return 0;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            scanf("%d",&a[i][j]);
    int L=0,R=0x3f3f3f3f,mid;
    while(L<=R){
        mid=L+R>>1;
        if(judge(mid))
            L=mid+1;
        else R=mid-1;
    }
    cout<<ans1<<" "<<ans2<<'
';
}
原文地址:https://www.cnblogs.com/zsben991126/p/12271335.html