Minimax Problem

D - Minimax Problem

首先先排除最暴力的\(O(n^2)\)做法。

当没有思路的时候,看看能不能够对答案进行二分,但是这个题是输出一对数组的下标,所以我们可以对最小值的最大值进行二分,看这个最大值存不存在。

对于每一行对 mid 的关系,我们可以对其进行状态压缩,大于等于的那一位就为1,小于的为0,并且用一个数组来存放数组下标,以便可以从得到的压缩的状态找到对应的数组。

另外一个巧妙之处在于,两个压缩的状态进行或运算|时,就完成了取\(max\)的操作。

代码:

// Created by CAD on 2020/1/15.
#include <bits/stdc++.h>
#define mst(name, value) memset(name,value,sizeof(name))
using namespace std;

const int maxn=3e5+5;
int a[maxn][10];
int n,m,x,y;
int vis[(1<<10)+5];
bool judge(int mid)
{
    mst(vis,0);
    for(int i=1;i<=n;++i)
    {
        int t=0;
        for(int j=1;j<=m;++j)
            if(a[i][j]>=mid) t|=(1<<(j-1));
        vis[t]=i;
    }
    for(int i=1;i<=(1<<10);++i)
        for(int j=1;j<=(1<<10);++j)
            if(vis[i]&&vis[j]&&((i|j)==(1<<m)-1)){
                x=vis[i],y=vis[j];return true;
            }
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            cin>>a[i][j];
    int l=0,r=1e9;
    x=y=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(judge(mid)) l=mid+1;
        else r=mid-1;
    }
    cout<<x<<" "<<y<<endl;
    return 0;
}
posted @ 2020-01-15 13:11  caoanda  阅读(306)  评论(0编辑  收藏  举报