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

2 years ago
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);
}
// 改出动态规划,记忆化搜索!
}