https://www.lanqiao.cn/problems/3824/learning
eg: n = 1234, k = 2
可以简单的列出这些选项:
● 1 + 2 + 34
● 1 + 23 + 4
● 12 + 3 + 4
利用 DFS 和回溯的思想,程序推导如下:
将 n 分成左右两部分,l 表示 left 左侧的值,r 表示 right 右侧的值。先将 l 加入 res,再将 r 作为新的 n 进入下一次 dfs,同时 k - 1。每次 dfs 结束后将 res - l,准备新的选择。如果 k == 0 表示没有多余的 '+' 号,本轮 dfs 结束,将剩下的数全部加入 res,再计算完 max 和 min 后,减掉刚刚加入的值。
dfs(1234, 2):
情况 1:1 + 2 + 34
n = 1234, k = 2
=> l = 1, r = 234, res =1, dfs(234, 1)
n = 234, k = 1
=> l = 2, r = 34, res = 3, dfs(34, 0)
n = 34, k = 0
=> res = 37, max = 37, min = 37, return
回溯:
res = 3
res = 1
情况 2:1 + 23 + 4
继续:
n = 234, k = 1
=> l = 23, r = 4, res = 24, dsf(4, 0)
n = 4, k = 0
=> res = 28, max = 37, min = 28, return
回溯:
res = 24
res = 1
res = 0
情况 3:12 + 3 + 4
继续:
n = 1234, k = 2
=> l = 12, r = 34, res = 12, dfs(34, 1)
n = 34, k = 1
=> l = 3, r = 4, res = 15, dfs(4, 0)
n = 4, k = 0
=> res = 19, max = 37, min = 19
结束
提醒:
如果用除法和取模获取 l 和 r,是不对的。
例如:n = 10000, k = 2。最终答案应该是 100 - 1 = 99。
如果使用取模获取 r,那么不管右侧剩下多少 0,最终 r 都为 0。这样做只考虑了数值而忽略了位数。
将 n 转为字符串可以准确的获取位数和数值。使用 substring 截取获得 l 和 r,使用 parseLong 转换为数值,再计算 res。
import java.util.Scanner;
public class Main {
private static long max = Long.MIN_VALUE;
private static long min = Long.MAX_VALUE;
private static long res;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String n = scanner.next();
int k = scanner.nextInt();
dfs(n, k);
System.out.println(max - min);
scanner.close();
}
private static void dfs(String s, int k) {
if (k == 0) {
long n = Long.parseLong(s);
res += n;
max = Math.max(max, res);
min = Math.min(min, res);
res -= n;
return;
}
for (int i = 0; s.length() - i - 1 >= k; i++) {
String l = s.substring(0, i + 1);
String r = s.substring(i + 1);
long n = Long.parseLong(l);
res += n;
dfs(r, k - 1);
res -= n;
}
}
}
标签:开心,min,res,dfs,34,蓝桥,算法,static,max
From: https://www.cnblogs.com/james-wangx/p/18114433