You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.1 KiB

2 years ago
package class_2022_03_4_week;
// 来自学员问题
// 大妈一开始手上有x个鸡蛋她想让手上的鸡蛋数量变成y
// 操作1 : 从仓库里拿出1个鸡蛋到手上x变成x+1个
// 操作2 : 如果手上的鸡蛋数量是3的整数倍大妈可以直接把三分之二的鸡蛋放回仓库手里留下三分之一
// 返回从x到y的最小操作次数
// 1 <= x,y <= 10^18
// 练一下,用平凡解做限制
public class Code08_EggXtoY {
// 彻底贪心!
public static int minTimes1(int x, int y) {
if (x <= y) {
return y - x;
}
// 0 0
// 1 2
// 2 1
int mod = x % 3;
// 鸡蛋拿到3的整数倍需要耗费的行动点数
int need = mod == 0 ? 0 : (mod == 1 ? 2 : 1);
return need + 1 + minTimes1((x + 2) / 3, y);
}
public static int minTimes2(int x, int y) {
if (x <= y) {
return y - x;
}
int limit = minTimes1(x, y);
int[][] dp = new int[x + limit + 1][limit + 1];
return process(x, y, 0, limit, dp);
}
// 当前鸡蛋数量cur目标aim
// 之前已经用了多少行动点pre
// limit : 一定行动点超过limit不需要尝试了
public static int process(int cur, int aim, int pre, int limit, int[][] dp) {
if (pre > limit) {
return Integer.MAX_VALUE;
}
if (dp[cur][pre] != 0) {
return dp[cur][pre];
}
int ans = 0;
if (cur == aim) {
ans = pre;
} else {
int p1 = process(cur + 1, aim, pre + 1, limit, dp);
int p2 = Integer.MAX_VALUE;
if (cur % 3 == 0) {
p2 = process(cur / 3, aim, pre + 1, limit, dp);
}
ans = Math.min(p1, p2);
}
dp[cur][pre] = ans;
return ans;
}
public static void main(String[] args) {
int max = 3000;
int testTime = 500;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int x = (int) (Math.random() * max) + 1;
int y = (int) (Math.random() * max) + 1;
int ans1 = minTimes1(x, y);
int ans2 = minTimes2(x, y);
if (ans1 != ans2) {
System.out.println("出错了!");
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("测试结束");
}
}