codeforces ECR 80 minimax problem (二分 构造)

11 篇文章 0 订阅
6 篇文章 0 订阅

题目大意:

有n个数列,选出第i,j个,我们可以得到新数列如下:

for k 1->m:

    a[z][k]=max(a[i][k],a[j][k])

问我们得到的新数列z中,哪一个的min(a[z][k])最大 即:

max(min (a[z][k])))  {k:1->m }

解题思路:

这种最小值最大 或者 最大值最小一般都是用二分来做。我们直接枚举答案mid,同时每次枚举时原数列中大于等于mid的置1。若它们中的任意两个的按位或等于2^m-1,那么我们认为是true 把答案往右偏。注意两两枚举数列的复杂度位n^2,但是注意到这里的m只为8,所以复杂度可以压缩到2^8,把相同的合并即可。

第一个问题:为什么可以用二分?因为这里满足 true true true false false结构,我们需要求出最后一个true的位置。

第二个问题:为什么想到这样构造:其实这样构造是蛮常见的技巧。即把数列中某个大于x的值全置为1,其它全置为0.

n,m=[int(i) for i in input().split(" ")]
arrmv=[]
for i in range(n):
    arrmv.append([int(i) for i in input().split(" ")])
x=0
y=int(1e9+1)
sucls=[0,0]
tols=[]
powls=[int(pow(2,i)) for i in range(10)]
twodarray=[0  for i in range(257)]
while x+1<y:
    mid = x+(y-x)//2
    for idx,ele in enumerate(twodarray):twodarray[idx]=0
    tols.clear()
    for topidx, eletop in enumerate(arrmv):
        tmp=0
        for idx,ele in enumerate(eletop):
            if ele>=mid:tmp+=powls[idx]
        
        if not twodarray[tmp]:
            twodarray[tmp]=1
            tols.append((tmp,topidx))
    sz=len(tols)
    suc=0
    no=int(pow(2,m))
    for i in range(sz):
        for j in range(i,sz):
            if tols[i][0] | tols[j][0] == no-1:
                sucls[0],sucls[1]=tols[i][1],tols[j][1]
                suc=1;
                break;
        if suc:break
    if suc:x=mid
    else:y=mid

print(sucls[0]+1,sucls[1]+1)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值