乘以/添加初始数字以获得目标数

时间:2015-05-31 07:16:33

标签: algorithm

假设我有一个目标号码n,例如5,我总是从数字1开始,我必须*2*3+1,直到我n。所以在这种情况下,我会*2两次,然后+1得到5。

我应该找到达到目标值的最少操作次数。我看到类似的问题是posted,但这需要一定数量的步骤,而我必须找出最少的步骤。有关如何解决这个问题的提示吗?

这是一个家庭作业问题。

4 个答案:

答案 0 :(得分:6)

可以将其视为搜索 DP 问题(是的,实际上它们都与 状态转换相关 ),关键点是定义搜索状态条件,假设n为正数,此处我们定义f[i] = inf, inf is a really large integer表示数字i无法访问,f[i] = k, k >= 0表示数字{{ 1}}至少可以i步骤到达。

如果k不是那么大,我们可以使用数组来存储从1到n的每个数字的最小步数。最初是nf[1] = 0。如果我们需要输出我们获取目标的方式(例如,输出5是f[i] = inf, 2 <= i <= n),我们可以使用另一个数组1 2 4 5来存储操作,定义pre表示数字{{1数字由pre[i] = j生成(例如,i表示数字4由数字2生成,因为2 * 2 = 4; j表示数字3由数字1生成,因为1 * 3 = 3):

pre[4] = 2

答案是pre[3] = 1

如何输出我们如何获得目标,我们使用 int inf = Integer.MAX_VALUE; f[1] = 0; pre[1] = -1; // pre[i] = -1 means i is the start point for(i=2;i<=n;i++) { f[i] = inf; pre[i] = -1; } for(int i=1;i<=n;i++) { // since each number is positive so smaller number cannot be produced via larger number, no need to consider > n issue if(f[i] == inf) { continue; } if(2*i <= n && f[i] + 1 < f[2*i]) { f[2*i] = f[i] + 1; pre[2*i] = i; // means number 2*i is produced by number i } if(3*i <= n && f[i] + 1 < f[3*i]) { f[3*i] = f[i] + 1; pre[3*i] = i; } if(i+1 <= n && f[i] + 1 < f[i+1]) { f[i+1] = f[i] + 1; pre[i+1] = i; } } 数组来恢复操作:

f[n]

如果pre非常大,您可能需要使用优先级队列来维护状态转换,并使用哈希集来维护每个数字的最小步骤。

答案 1 :(得分:2)

我认为前往这里的方法是向后工作。从someDivId开始,尝试最大程度减少它的操作,然后尝试列表中的第二个等等。代码看起来像这样:

n

基本上,我们的想法是尽可能快地到达string actions = ""; int i = n, count = 0; while (i > 1) { count++; if (i % 3 == 0) { i = i / 3; actions = "*3 " + actions; continue; } if (i % 2 == 0) { i = i / 2; actions = "*2 " + actions; continue; } i--; actions = "+1 " + actions; } 。我不确定这是最少的步骤,但它似乎是一个良好的开端。

答案 2 :(得分:1)

您是否考虑过AI方法?

将问题视为树中的搜索:根是1,树中的每个节点X都有3个儿子:2 * X,3 * X,X + 1.

你可以构建整个树(每个节点X,其中X&gt; n不应该有更多的儿子)并使用BFS来找到从根到具有值n的节点的最短路径,或者如果图形不适合内存,请使用A*算法。

答案 3 :(得分:0)

这将为您提供有保障的最短路径。

static int result(int a, int b){
    int answer = 0;
    while (a < b){
        if (b % 3 == 0 && b / 3 >= a){
            b = b / 3;
            answer++;
        }
        else if ((b - 1) % 3 == 0 && (b - 1) / 3 >= a){
            b = b - 1;
            b = b / 3;
            answer += 2;
        }
        else if (b % 2 == 0 && b / 2 >= a){
            b = b / 2;
            answer++;
        }
        else{
            b = b - 1;
            answer++;
        }
    }

    return answer;
}