1

这是对我之前的问题(关于一个旧的顶级编码器之谜)的跟进。

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

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

我猜(虽然没有证明)问题是NP完全的。你怎么看?你如何将一个众所周知的 NP 完全问题简化为这个问题?

4

3 回答 3

1

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

于 2011-12-08T11:28:22.613 回答
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。

当然,更有趣的是 base 10 表壳的硬度。

于 2011-12-08T12:43:07.570 回答
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”)。

于 2011-12-08T18:58:42.323 回答