旧编码器谜语的复杂性:通过插入+来制作数字

时间:2011-12-08 11:21:09

标签: algorithm complexity-theory reduction np

这是my previous question(关于一个旧的顶级编码器之谜)的后续行动。

  

给定一串数字,找到字符串所需的最小加法数等于某个目标数。每次添加相当于在数字串中的某处插入加号。插入所有加号后,照常计算总和。

     

例如,考虑" 303"目标总和为6.最佳策略是" 3 + 03"。

我猜(虽然没有证明)问题是NP完全的。 你怎么看?你如何减少一个众所周知的NP完全问题呢?

3 个答案:

答案 0 :(得分:1)

如果您在数字后添加预期结果,那么很明显这是http://en.wikipedia.org/wiki/Partition_problem

答案 1 :(得分:1)

如果基数是参数,则子集和减少。设x 1 ,...,x n ,s> 0是子集和的实例,并且令S = x 1 + ... + x n 。在基数S + 1中,让Top Coder输入为

x 1 0 x 2 0 ... x n 0

求和到(S - s)(S + 1)+ s。

当然,更有趣的是10号底座的硬度。

答案 2 :(得分:0)

这是智力上好奇(或懒惰)的解决方案代码。 JavaScript的:

var A = "12345";

function riddle(s, n) {
 for(var ins=0; ins<s.length; ins++) {
  if( recurse(n, "", s, ins) ) {
   console.log(ins + " insertions");
   break;
  }
 }
}

function recurse(n, t, s, ins) {
 if(ins == 0) {
 // reached the end does it equal the number?
  var temp = (t != "" ? t + " + " : "") + s;
  if( eval(temp) == n ) {
   console.log(temp);
   return true;
  }
  return false;
 } else if(s.length - ins > 0) {
  for(var x=1; x<s.length; x++) {
   var temp = (t != "" ? t + " + " : "") + s.substring(0, x);
   if( recurse(n, temp, s.substring(x), ins-1) ) {
    return true;
   }
  }
 }
 return false;
}

riddle(A, 12345);
riddle(A, 357);
riddle(A, 15);

指数时间,可能性的数量是2 ^(n-1),当n = 3时,T(n)= 4;当n = 5时,T(n)= 32。

如果您认为插入次数与设置大小相对应,并且这些插入的位置是设置元素,则可以看到与子集和的关系。此外,与Subset Sum一样,验证者是多项式时间,只是对数字集合求和,(上面代码中的“eval(temp)== n”)。