D. Minimax Problem
time limit per test
5 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output
You are given nn arrays a1a1, a2a2, ..., anan; each array consists of exactly mm integers. We denote the yy-th element of the xx-th array as ax,yax,y.
You have to choose two arrays aiai and ajaj (1≤i,j≤n1≤i,j≤n, it is possible that i=ji=j). After that, you will obtain a new array bb consisting of mmintegers, such that for every k∈[1,m]k∈[1,m] bk=max(ai,k,aj,k)bk=max(ai,k,aj,k).
Your goal is to choose ii and jj so that the value of mink=1mbkmink=1mbk is maximum possible.
Input
The first line contains two integers nn and mm (1≤n≤3⋅1051≤n≤3⋅105, 1≤m≤81≤m≤8) — the number of arrays and the number of elements in each array, respectively.
Then nn lines follow, the xx-th line contains the array axax represented by mm integers ax,1ax,1, ax,2ax,2, ..., ax,max,m (0≤ax,y≤1090≤ax,y≤109).
Output
Print two integers ii and jj (1≤i,j≤n1≤i,j≤n, it is possible that i=ji=j) — the indices of the two arrays you have to choose so that the value of mink=1mbkmink=1mbk is maximum possible. If there are multiple answers, print any of them.
Example
input
Copy
6 5 5 0 3 1 2 1 8 9 1 3 1 2 3 4 5 9 1 0 3 7 2 3 0 6 3 6 4 1 7 0
output
Copy
1 5
1 /* 2 看到题目首先想到的就是二分答案,那么找到一个可能的答案之后就可以把所有数列转化成01数列,1代表该位置的数大于等于答案,0代表该位置的数小于答案。 3 4 选择两个数列使其满足答案,也就是使这两个数列的或和为(1<<m)-1,很显然不能n*n的枚举每个数列,但是2^8只有256,所以可以直接枚举数列对应的二进制数,判断答案是否可行,如果可行,就可以O(n)地寻找可行解 5 */ 6 #include<iostream> 7 #include<cstdio> 8 #include<bitset> 9 #include<cstring> 10 using namespace std; 11 int n,m,a[300010][10],ans1,ans2; 12 int b[300010]; 13 bool vis[300]; 14 bool check(int x){ 15 memset(b,0,sizeof(b)); 16 for(int i=1;i<=n;i++){ 17 for(int j=1;j<=m;j++){ 18 if(a[i][j]>=x)b[i]^=1<<(j-1); 19 } 20 } 21 memset(vis,0,sizeof(vis)); 22 for(int i=1;i<=n;i++)vis[b[i]]=1; 23 bool flag=0; 24 int s1=0,s2=0; 25 for(int sta1=0;sta1<(1<<m);sta1++){ 26 for(int sta2=sta1;sta2<(1<<m);sta2++){ 27 if((sta1|sta2)==(1<<m)-1&&vis[sta1]&&vis[sta2]){ 28 s1=sta1;s2=sta2; 29 flag=1; 30 break; 31 } 32 } 33 if(flag)break; 34 } 35 if(!flag)return 0; 36 for(int i=1;i<=n;i++){ 37 if(b[i]==s1){ 38 ans1=i; 39 break; 40 } 41 } 42 for(int i=1;i<=n;i++){ 43 if(b[i]==s2){ 44 ans2=i; 45 break; 46 } 47 } 48 return 1; 49 } 50 int main(){ 51 scanf("%d%d",&n,&m); 52 for(int i=1;i<=n;i++) 53 for(int j=1;j<=m;j++){ 54 scanf("%d",&a[i][j]); 55 } 56 int l=0,r=1000000000; 57 while(l<=r){ 58 int mid=(l+r)>>1; 59 if(check(mid)){ 60 l=mid+1; 61 } 62 else r=mid-1; 63 } 64 printf("%d %d\n",ans1,ans2); 65 return 0; 66 }
原文地址:https://www.cnblogs.com/thmyl/p/12237546.html