计算不匹配袜子组合的总数

时间:2017-11-01 01:35:32

标签: algorithm optimization combinatorics

这是2015年ICPC西北规划竞赛的问题之一,我想知道是否有更简单或更有效的方法。

问题在于:

“弗雷德喜欢穿不匹配的袜子。这有时意味着他必须提前计划。 假设他的袜子抽屉有一个红色,一个蓝色和两个绿色袜子。如果他穿了 蓝色的红色,他穿着匹配的绿色袜子。他把两个放在一起 如果他将红色与绿色配对,然后将蓝色与绿色配对则不匹配。鉴于 他的袜子抽屉的内容,他可以将多少双不匹配的袜子放在一起?“

以下是一个示例输入:

2017/11/01 04:27:22 [error] 13451#13451: *1 open() "/usr/share/nginx/html/static/img/search.svg" failed (2: No such file or directory), client: 127.0.0.1, server: asknow.local, request: "GET /static/img/search.svg HTTP/1.1", host: "www.asknow.local"

Color 1 -> 4 socks

Color 2 -> 3 socks

Color 3 -> 7 socks

Color 4 -> 11 socks

我正在做的方法是首先将输入读入数组并逐渐对其进行排序。这样我就会在阵列末尾拥有最多的袜子。从这里开始,我基本上比较Color 5 -> 4 socksarr[i]并获得它们之间的最小值。将其添加到总数中,保存剩余部分,然后重复进入数组的过程。例如,使用示例输入它看起来像这样:

排序数组:arr[i-1]

[3,4,4,7,11] 1:3 socks ---> 1:3 socks ---> 1:0 socks

---> 1:0 socks 2:4 socks ---> 2:4 socks ---> 2:1 socks

---> 2:1 socks 3:4 socks ---> 3:4 socks ---> 3:0 socks

---> 3:0 socks 4:7 socks ---> 4:0 socks ---> 4:0 socks

---> 4:0 socks 5:11 socks ---> 5:4 socks ---> 5:0 socks

---> 5:0 socks总计= 14种不匹配的袜子组合。这似乎太天真了一种方法。有没有人对如何优化它有任何想法?如有必要,我可以发布我的代码。

3 个答案:

答案 0 :(得分:1)

我认为通过检查不同袜子颜色的所有可能分组到2桩,可以找到最佳解决方案。对于每个这样的分组p可以制作奇数对袜子,其中p是最小桩中的袜子数。您希望分组提供最大p。您可以递归地将所有可能的袜子分组生成为2个桩。

这里有一些Java代码来说明:

public static void main(String[] args)
{
    int[] socks = {3,4,4,7,11};
    System.out.println(count(0, 0, socks, 0));
}

static int count(int a, int b, int[] socks, int i)
{
    if(i == socks.length)
    {
        return Math.min(a, b);
    }

    return Math.max(count(a+socks[i], b,          socks, i+1), 
                    count(a,          b+socks[i], socks, i+1));
}

输出:

14

答案 1 :(得分:1)

“希望在这个时候更正确!”方法

步骤1:检查是否剩下2种或更多颜色。如果没有或者剩下一种颜色你就完成了(找不到更多对)。

步骤2:找到一个具有最低非零数的颜色

步骤3:排除最低计数的颜色(如果所有颜色具有相同的计数);找到最高计数并确定共享最高计数的颜色数

步骤4:排除最低计数的颜色和最高计数的所有颜色;试图找到第二高的数量。

步骤5a:如果计数第二高,则计算amount_to_pair = min(highest_count - second_highest_count, lowest_count)

步骤5b:如果没有第二高的计数,请计算amount_to_pair = lowest_count

步骤6:通过将袜子与具有最低计数的袜子配对,尽可能均匀地使用具有最高计数的颜色(例如,如果有9个红色袜子,20个蓝色袜子和20个绿色,则创建amount_to_pair对袜子;然后创造5对“红色和蓝色”对和4“红色和绿色”对。

第7步:转到第1步。

示例(评论中提到的病理案例):

初始条件

Color 1 -> 1 socks
Color 2 -> 20 socks
Color 3 -> 80 socks
Color 4 -> 81 socks

第一次迭代:

Color 1 -> 1 socks (lowest non-zero count)
Color 2 -> 20 socks
Color 3 -> 80 socks (2nd highest count)
Color 4 -> 81 socks (highest count)

Amount to remove = min(81-80, 1) = 1

Color 1 -> 1-1=0 socks (lowest non-zero count)
Color 2 -> 20 socks
Color 3 -> 80 socks
Color 4 -> 81-1=80 socks (highest count)

Results so far:
   (1 pair of colour 1 and colour 4)

第二次迭代:

Color 1 -> 0 socks
Color 2 -> 20 socks (lowest non-zero count)
Color 3 -> 80 socks (highest count)
Color 4 -> 80 socks (highest count)

Amount to remove = 20

Color 1 -> 0 socks
Color 2 -> 20-20=0 socks (lowest non-zero count)
Color 3 -> 80-(20/2)=70 socks (highest count)
Color 4 -> 80-(20-20/2)=70 socks (highest count)

Results so far:
   (1 of colour 1 and colour 4)
   (10 of colour 2 and colour 3)
   (10 of colour 2 and colour 4)

第三次迭代:

Color 1 -> 0 socks
Color 2 -> 0 socks
Color 3 -> 70 socks (lowest non-zero count)
Color 4 -> 70 socks (highest count)

Amount to remove = 70

Color 1 -> 0 socks
Color 2 -> 0 socks
Color 3 -> 70-70=0 socks (lowest non-zero count)
Color 4 -> 70-70=0 socks (highest count)

Results so far:
   (1 of colour 1 and colour 4)
   (10 of colour 2 and colour 3)
   (10 of colour 2 and colour 4)
   (70 of colour 3 and colour 4)

原始方法

警告:以下方法在各种病理情况下会给出错误的结果(并且已由上述算法更新/替换)。我把它留在这里给出一些评论的背景

开始条件:

Color 1 -> 4 socks
Color 2 -> 3 socks
Color 3 -> 7 socks
Color 4 -> 11 socks
Color 5 -> 4 socks

查找最高计数和最低计数;并取消最低计数,以便它不再存在:

Color 1 -> 4 socks
Color 3 -> 7 socks
Color 4 -> 11-3=8 socks
Color 5 -> 4 socks

Results so far:
   (3 of colour 2 and colour 4)

再做一次:

Color 3 -> 7 socks
Color 4 -> 8-4=4 socks
Color 5 -> 4 socks

Results so far:
   (3 of colour 2 and colour 4)
   (4 of colour 1 and colour 4)

再做一次:

Color 3 -> 7-4=3 socks
Color 5 -> 4 socks

Results so far:
   (3 of colour 2 and colour 4)
   (4 of colour 1 and colour 4)
   (4 of colour 4 and colour 3)

再做一次:

Color 5 -> 4-3=1 sock

Results so far:
   (3 of colour 2 and colour 4)
   (4 of colour 1 and colour 4)
   (4 of colour 4 and colour 3)
   (4 of colour 3 and colour 5)

停止,因为只剩下一种颜色。

答案 2 :(得分:1)

构建图形数据结构。每个袜子都是顶点。从每个顶点到另一种颜色的所有顶点创建边。

现在找到maximum matching的力量 - 没有公共顶点的边集的大小。

您可以在多项式时间O(V ^ 2 * E)中使用Edmonds algorithm构建最大匹配。似乎该任务的图形将是密集的,因此复杂性倾向于O(V ^ 4)。还存在Micali和Vazirani算法,其复杂性较低(不了解实现硬度)。

如果你的任务本身不需要最大匹配 - 只有边数,那么可以使用基于Tutte矩阵定理的随机Lovasz算法计算该值。 (我没有找到简明的英文描述 - 或许术语可能有所不同,俄语中的短文是here