D. Minimax Problem------二分+状态压缩/思维

You are given n arrays a1, a2, …, an; each array consists of exactly m integers. We denote the y-th element of the x-th array as ax,y.

You have to choose two arrays ai and aj (1≤i,j≤n, it is possible that i=j). After that, you will obtain a new array b consisting of m integers, such that for every k∈[1,m] bk=max(ai,k,aj,k).

Your goal is to choose i and j so that the value of mink=1mbk is maximum possible.

Input
The first line contains two integers n and m (1≤n≤3⋅105, 1≤m≤8) — the number of arrays and the number of elements in each array, respectively.

Then n lines follow, the x-th line contains the array ax represented by m integers ax,1, ax,2, …, ax,m (0≤ax,y≤109).

Output
Print two integers i and j (1≤i,j≤n, it is possible that i=j) — the indices of the two arrays you have to choose so that the value of mink=1mbk is maximum possible. If there are multiple answers, print any of them.

Example
inputCopy

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
outputCopy
1 5

题意:给你n个长度为m的数组。可以选两个下标i,j(1<=i<=j<=n)。构造成一个新的数组bi=max(aik,ajk).
要求你选择两个下标构成的新数组的最小值最大,然后输出这两个下标

解析:最小值最大 二分。
因为m<=8,对于每个数组,每个元素a[i][j]>=mid 则二进制第j位为1,否则为0.用一个状态x存在sta[x],然后记录其下标sta[x]=i;
两个for 暴力遍历每个状态 ((1<<m)^2)
如果(i|j)==(1<<m)-1 则说明存在两个数组一定能构成大于等于mid的新数组。
记录答案ansx,ansy
不断二分,答案会逐渐最优。

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
const int M=256;
int a[N][10];
int sta[N];
int ansx,ansy;
int n,m;
bool check(int mid)
{
	for(int i=0;i<(1<<m);i++) sta[i]=0;//初始化所有状态 
	for(int i=1;i<=n;i++)
	{
		int x=0;
		for(int j=1;j<=m;j++)
			if(a[i][j]>=mid)
				x|=(1<<(j-1));
		sta[x]=i;
	 } 
	 for(int i=0;i<(1<<m);i++)
	 	for(int j=i;j<(1<<m);j++)
	 	{
	 		if(sta[i]&&sta[j])
	 		{
	 			if((i|j)==(1<<m)-1)
	 			{
	 				ansx=sta[i];
	 				ansy=sta[j];
	 				return 1;
				 }
			 }
		 }
	
	return 0;
}
int main()
{
	cin>>n>>m;
	int l=1e9,r=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			l=min(l,a[i][j]);
			r=max(r,a[i][j]);
		}
	while(l<=r)
	{
		int mid=l+r>>1;
		if(check(mid)) l=mid+1;
		else r=mid-1;
	}
	cout<<ansx<<" "<<ansy<<endl;
}

发布了284 篇原创文章 · 获赞 6 · 访问量 3784

猜你喜欢

转载自blog.csdn.net/qq_43690454/article/details/104028765
今日推荐