Algorithm 检测整数是否可以写为给定整数的乘积

Algorithm 检测整数是否可以写为给定整数的乘积,algorithm,math,Algorithm,Math,我有一组给定的整数: A[] = { 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 40, 50, 100, 500 } 我想检查一个给定的整数T是否可以写成a[]中数字的倍数; 编辑澄清: []中的任何数字都可以使用。如果使用,则只能使用一次。 ex60是一个有效的T.60=30*2。 此外,90是有效的。90=3*5*6 检查哪些数字可以构成整数T 如果不能将数字T写成该数字的倍数,则返回与给定T最接近的2个整数,该整数可以通过这种方式写入。 第二部分和

我有一组给定的整数:

A[] = { 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 40, 50, 100, 500 }
我想检查一个给定的整数T是否可以写成a[]中数字的倍数; 编辑澄清: []中的任何数字都可以使用。如果使用,则只能使用一次。 ex60是一个有效的T.60=30*2。 此外,90是有效的。90=3*5*6

检查哪些数字可以构成整数T

如果不能将数字T写成该数字的倍数,则返回与给定T最接近的2个整数,该整数可以通过这种方式写入。 第二部分和第三部分,如果有人帮我完成第一部分,我想我可以自己解决

我知道这是一个算法问题,甚至是一个数学问题,但如果有人能帮忙,请帮忙

不是家庭作业。见下面的评论

解决方案。 对于所有的答案,我都非常满意。我的答案很特别,但作者选择删除它,我不知道为什么,因为它是正确的。 我不记得你的名字了

带扭曲的解决方案代码作者的算法使用了多次乘法器。这一次只使用了一次乘法器

int oldT = 0;
        HashMap<Integer, Boolean> used = new HashMap<Integer, Boolean>();
        while (T != 1 && T != -1) {
            oldT = T;
            for (int multiple : A) {
                if (!used.containsKey(multiple)) {
                    if (T % multiple == 0) {
                        T = T / multiple;
                        used.put(multiple, true); 
                    }
                }
            }
            if (oldT == T)
                return false;
        }
        return true;

如果T不是很大,比如说,<10^7,这是直DP

a[1] = true; // means that number '1' can be achieved with no multipliers
for (every multiplier x) {
   for (int i = T; i > 0; --i) {
      if (a[i] and (i * x <= T)) {
          // if 'i' can be achieved and 'x' is a valid multiplier,
          // then 'i * x' can be achieved too
          a[i * x] = true;
      }
   }
}
假设每个乘数只能使用一次。 现在,如果有另一个数组b[i]存储用来实现i的乘法器,就可以找到T的分解

如果你时间不多,有很多在线内容需要你熟悉动态编程。它应该让你知道如何处理这些问题。举个例子,这个看起来不错
我不确定你到底在问什么

如果用户可以从这些数字中选择n*一个,那么请注意素数为2、3、5和7,因此如果您的数字可以被2、3、5或7整除,那么将其除掉,就得到了n*那个数字

如果您必须将这些数字相乘,但可以将它们相乘多次,那么请再次注意,您所有的数字都会被分解为2、3、5和7的幂。检查一个赌注是否只能被这些分开,直到你不能再分开为止,然后看看你是否剩下1,并计算你被每个分开的次数

如果你必须在不替换的情况下将这些数字相乘,那么再次找到素数分解,并从列表中删除使幂呈现最偶数的数字。如果您成功地删除了所有的倍数,那么您就完成了


除最后一种情况外,所有可以下注的数字都非常密集,因此您只需向上或向下并再次检查即可找到最近的数字。在最后一种情况下,寻找附近的东西可能有点棘手;您可能只想形成一个可能的低赌注表,并从中提出一些建议,假设用户不会下注2*3*4*5*6*7*8*10*15*…

这看起来像是在引用一个家庭作业问题。。。如果是的话,请注明家庭作业不,这不是家庭作业问题。我正在开发一个自己的赌博android程序,唯一允许下注的是这些数字的倍数*0.3欧元。所以这不是一个家庭作业,而是我正在开发的程序的一个功能。不清楚给定整数的乘法是什么意思。不应该是某种[]的产物吗?数字可以被多次使用吗?或者,它是乘积的总和吗?例如,700=500+2*100。一辆车能有多大?如果它不大,你可以计算它的所有子集,然后将它们相乘,得到所有可能的“赌注”列表,然后对其进行二进制搜索。他删除了他的解决方案,因为它在一些示例中不起作用。比如A=[2,6]和T=6。首先将T除以2,得到3,然后卡住。不幸的是,暴力解决方案有时会失败:不,不是每个乘数都必须使用。这是一个棘手的问题,我找不到解决方案。它可以是2或3等。t也代表金钱,所以是的,不是每个乘数都必须准确使用。如果有效乘数为2和3,那么“a”将为1、2、3和6设置“true”。还要注意,链接中的第一个问题非常类似:它只是使用加法而不是乘法。使用动态规划的想法很好,但这不是一个非常有效的实现。我想这要由读者来填写了。例如,存储一个“到目前为止的最大真实值”,永远不要从T/x以上开始,因为这无论如何都不会通过条件,等等。直接将它们全部分割策略将不起作用。如果你只有乘数2和6,T=6,那么你首先将T除以2,得到3,然后陷入困境。是的,我考虑过为所有可能的赌注预先形成一个排序表,但是对于一个移动设备来说,其大小将是巨大的。非常感谢您的支持suggestions@Nikita-这就是为什么我说,无论哪个数字使权力呈现最均衡。这是一种通常有效的启发式方法;当然,对于任意的数字集来说并不总是如此,但对于给定的数字集来说却相当不错。@weakwire-表格并不庞大,16项中的每一项都有是或否的答案,即2^16个条目。如果你扔掉那些难以置信的大桌子,桌子会更小。是的 e与Nikita建议的策略相同,只是计算效率更高,因为你保证在16*2^16步中找到每个解,而在Nikita中,你有16*T,其中T是你的上界。