526.5_1000

从N个三元组{matches, red, blue}取出尽量多的组,使得取出的{matches}的任何非空子集的异或都不为0,也就是两个人用来玩NIM游戏,先手必赢。在必赢的情况下,求出最小的sum{red} * sum{blue}..

问题1:取出的{matches}任何非空子集都是先手必赢,可以采用贪心的方法,利用|{matches}| == 矩阵的质。

问题2:使得sum{red} * sum{blue}最小,我们定出贪心的顺序。

对于问题2,

对于每个最优解OPT, 定义: sigma{OPT.red[i]} = R and sigma{OPT.blue[i]} = B.
定义: w[i] = red[i] + t * blue[i] (t = R / B)
所以: sigma{OPT.w[i]} = 2 * R. 
对于其他解 S, 定义: sigma{S.red[i]} = r ,sigma{S.blue[i]} = b. 
那么 sigma{S.w[i]} =  r + b * t >= 2 * sqrt(r * b * t) >= 2 * sqrt(R * B * t) = 2 * R

所以: sigma{S.w[i]} >= sigma{OPT.w[i]}. 而且当且仅当S是最优解,等号成立。

由于有N个数,最多会有(N*N) 个t,枚举之。

扫描二维码关注公众号,回复: 1389444 查看本文章

补充:

有N个二元组{a,b},选出M个使得sum{a} * sum{b} 最小。

用堆可以在N * N * logN的时间内解决。

猜你喜欢

转载自splayx.iteye.com/blog/1407604