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