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.

112 lines
3.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class37;
// 来自字节
// 扑克牌中的红桃J和梅花Q找不到了为了利用剩下的牌做游戏小明设计了新的游戏规则
// 1) A,2,3,4....10,J,Q,K分别对应1到13这些数字大小王对应0
// 2) 游戏人数为2人轮流从牌堆里摸牌每次摸到的牌只有“保留”和“使用”两个选项且当前轮必须做出选择
// 3) 如果选择“保留”当前牌,那么当前牌的分数加到总分里,并且可以一直持续到游戏结束
// 4) 如果选择“使用”当前牌,那么当前牌的分数*3加到总分上去但是只有当前轮下一轮下下轮生效之后轮效果消失。
// 5) 每一轮总分大的人获胜
// 假设小明知道每一轮对手做出选择之后的总分,返回小明在每一轮都赢的情况下,最终的最大分是多少
// 如果小明怎么都无法保证每一轮都赢,返回-1
public class Code02_GameForEveryStepWin {
// public static max(int[] cands, int[] sroces) {
// return f(cands, sroces, 0, 0, 0, 0);
// }
// 当前来到index位置牌是cands[index]值
// 对手第i轮的得分sroces[i]
// int hold : i之前保留的牌的总分
// int cur : 当前轮得到的,之前的牌只算上使用的效果,加成是多少
// int next : 之前的牌对index的下一轮使用效果加成是多少
// 返回值如果i...最后,不能全赢,返回-1
// 如果i...最后,能全赢,返回最后一轮的最大值
// index -> 26种
// hold -> (1+2+3+..13) -> 91 -> 91 * 4 - (11 + 12) -> 341
// cur -> 26
// next -> 13
// 26 * 341 * 26 * 13 -> ? * (10 ^ 5)
public static int f(int[] cands, int[] sroces, int index, int hold, int cur, int next) {
if (index == 25) { // 最后一张
int all = hold + cur + cands[index] * 3;
if (all <= sroces[index]) {
return -1;
}
return all;
}
// 不仅最后一张
// 保留
int all1 = hold + cur + cands[index];
int p1 = -1;
if (all1 > sroces[index]) {
p1 = f(cands, sroces, index + 1, hold + cands[index], next, 0);
}
// 爆发
int all2 = hold + cur + cands[index] * 3;
int p2 = -1;
if (all2 > sroces[index]) {
p2 = f(cands, sroces, index + 1, hold, next + cands[index] * 3, cands[index] * 3);
}
return Math.max(p1, p2);
}
// 26 * 341 * 78 * 39 = 2 * (10 ^ 7)
public static int process(int[] cards, int[] scores, int index, int hold, int cur, int next) {
if (index == 25) {
int all = hold + cur + cards[index] * 3;
if (all > scores[index]) {
return all;
} else {
return -1;
}
} else {
int d1 = hold + cur + cards[index];
int p1 = -1;
if (d1 > scores[index]) {
p1 = process(cards, scores, index + 1, hold + cards[index], next, 0);
}
int d2 = hold + cur + cards[index] * 3;
int p2 = -1;
if (d2 > scores[index]) {
p2 = process(cards, scores, index + 1, hold, next + cards[index] * 3, cards[index] * 3);
}
return Math.max(p1, p2);
}
}
// cur -> 牌点数 -> * 3 之后是效果
// next -> 牌点数 -> * 3之后是效果
public static int p(int[] cands, int[] sroces, int index, int hold, int cur, int next) {
if (index == 25) { // 最后一张
int all = hold + cur * 3 + cands[index] * 3;
if (all <= sroces[index]) {
return -1;
}
return all;
}
// 不仅最后一张
// 保留
int all1 = hold + cur * 3 + cands[index];
int p1 = -1;
if (all1 > sroces[index]) {
p1 = f(cands, sroces, index + 1, hold + cands[index], next, 0);
}
// 爆发
int all2 = hold + cur * 3 + cands[index] * 3;
int p2 = -1;
if (all2 > sroces[index]) {
p2 = f(cands, sroces, index + 1, hold, next + cands[index], cands[index]);
}
return Math.max(p1, p2);
}
// 改出动态规划,记忆化搜索!
}