D. Minimax Problem(二分+状压)

题意:给你一个n*m的矩阵a,然后定义一个数组b,我们可以在a数组中随机选择两行i,j(1<=i,j<=n,i和j可以相等)对于k∈[1,m]b_k = max(a_i,k,a_j,k),之后我们需要去最大化k∈[1,m],b_k的最小值

解法:实际解法我们可以把题意简单化就是要最大化最小值,那么可以考虑二分答案

#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
const int N = 1 << 10;
int a[maxn][10];
int vis[N];
int ans1,ans2;
int n,m;
bool check(int x){
	memset(vis,0,sizeof(vis));
	for(int i = 1; i <= n; i++){
		int va = 0;
		for(int j = 1; j <= m; j++){
			//如果当前位置大于x 那么就直接或上当前的值
			//表示当i位置可达>=x 
			if(a[i][j] >= x)
			va |= 1 <<(j-1);
		}
		vis[va] = i;
	}
	for(int i = 0; i<(1 << m); i++){
		if(vis[i]){
			for(int j = 0; j<(1 << m); j++){
				if(vis[j]){
					if((i|j) == (1 << m) - 1){
						ans1 = vis[i];
						ans2 = vis[j];
						return true;
					}
				}
			}
		}
	}
	return false;
} 
int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++)cin >> a[i][j];
	}
	//题意任意选择两行i,j首先得到b数组
	//考虑二分 直接二分答案 
	int l = 0,r = 0x3f3f3f3f;
	while(l <= r){
		int mid = l + r >> 1;
		if(check(mid))l = mid + 1;
		else r = mid - 1;
	} 
	cout << ans1 << " " << ans2 << endl;```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值