我想要转换为3的整数中的数字
数字可以转换为具有相同位数且没有前导零的其他数字。
将数字转换为其他数字的成本是相应数字的绝对差值之和。例如,将235转换为331的成本是5(因为相应数字的绝对差值是| 3-2 | + | 3-3 | + | 1-5 |,这是| 1 | +0 + | -4 | = 5。
Number= 66 cost= 3
在66的成本≤3中可以创建的数字是36,45,54,57,63,66,69,75,78,87,96。所以答案是11。
我的方法:
我将输入作为字符串和
使用递归调用进行所有组合
public static void cal(int len , int sum , int c , String SS){
if(c>cost) return ;
if(len==SS.length()){
if(sum%3==0) ans++;
return;
}
for(int i=0;i<=9;i++){
int xx =Math.abs(i-Character.getNumericValue(SS.charAt(len)));
cal(current+1, len+1, sum+i, c+xx, SS);
}
}
因为MSB不允许零。
for(int i=1;i<=9;i++){
int xx =Math.abs(i-Character.getNumericValue(SS.charAt(0)));
cal(i, 1, i, xx , SS);
}
例如237946732463272737 60
此输出我的代码无法在特定时间内计算
如何改进算法
答案 0 :(得分:1)
这就是我解决问题的方法:你需要一个 dp [P] [C] [S] 数组,其中 dp [i] [j] [k] 指定您在数字的数字表示中位置 i ,您有 j 金额,到目前为止的总和 k 。
基本的想法是,如果你改变(或不改变)一个数字问题减少到(左数字,左钱,总和)的子问题,每个数字最多有10个选项,所以为了填补每个状态,你需要一个10的循环所以时间复杂度 O(P * C * S * 10)。由于N在最大P = 19(数字)时仅为最大10 ^ 18,因此C = 200(如您所述)并且最大值为9 * 18(数字之和)。因此,对于给定的时间约束以及 O(P * C * S)的存储器,该算法是合适的。
因此,除了递归逻辑之外,还需要使用memoization(存储已访问状态的答案)以及递归。
答案 1 :(得分:0)
对于这样的问题,使用递归生成所有可能性会导致随着输入大小的增长而呈指数增长的时间。如果你想要一个能够快速为大输入尺寸做到这一点的算法,你最好考虑一种计算方法,而不会产生所有可能性。
你可能想要这样一个事实:一个可以被3整除的数字的总和也可以被3整除。
所以也许看看你的原始数字的数字总和给出模数3.如果它是1,例如,你所做的数字值的总变化需要是2模3.然后你可以从那里进步