从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,枚举之。
补充:
有N个二元组{a,b},选出M个使得sum{a} * sum{b} 最小。
用堆可以在N * N * logN的时间内解决。