古老的 Top Coder 谜语的复杂性:通过插入 + 来生成数字

发布于 2024-12-20 07:53:02 字数 355 浏览 1 评论 0原文

这是我之前的问题的后续问题(关于一个古老的顶级程序员之谜)。

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

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

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

This is a follow up to my previous question (about an old top coder riddle).

Given a string of digits, find the minimum number of additions required for the string to equal some target number. Each addition is the equivalent of inserting a plus sign somewhere into the string of digits. After all plus signs are inserted, evaluate the sum as usual.

For example, consider "303" and a target sum of 6. The best strategy is "3+03".

I guess (not proved it though) the problem is NP-complete.
What do you think? How would you reduce a well-known NP-complete problem to this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

转身泪倾城 2024-12-27 07:53:02

如果将基作为参数,则子集和会减少。设 x1, …, xn, s > 0 是子集和的实例,令 S = x1 + … + xn。在基数 S + 1 中,让 Top Coder 输入为

x1 0 x2 0 … xn 0

总和为 (S - s) (S+1)+s。

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

If the base is made a parameter, then there is a reduction from subset sum. Let x1, …, xn, s > 0 be the instance of subset sum and let S = x1 + … + xn. In base S + 1, let the Top Coder input be

x1 0 x2 0 … xn 0

summing to (S - s) (S + 1) + s.

Much more interesting of course is the hardness of the base 10 case.

两个我 2024-12-27 07:53:02

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

If you add the expected result after the number it is clear that this is the http://en.wikipedia.org/wiki/Partition_problem ?

复古式 2024-12-27 07:53:02

这是为求知欲强(或懒惰)的人提供的解决方案代码。
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”)。

Here's the solution code for the intellectually curious (or lazy).
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);

Exponential time, the number of possibilities is 2^(n-1), when n = 3, T(n) = 4; when n = 5, T(n) = 32.

If you consider the number of insertions corresponds with the set size, and the positions of those insertions are the set elements, you can see the relation to subset sum. Also, like Subset Sum the verifier is polynomial time, just summing the set of digits, (the "eval(temp) == n" in the code above).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文