德州扑克葫芦限制问题
-
13到1张牌,3+2相同的牌组成最大数获胜
-
设置了最大限制
-
暴力枚举
- 哈希统计每种牌的数量
- 枚举找出满足下面条件的组合[a大于2,b大于1],[a等于b时a大于4]
- 检查满足条件的组合的值是否小于max+1
- 保留最大组合,没有则返回[0,0]
-
排序和双指针
- 统计牌的数量
- 从大到小排序
- 固定a,从大到小枚举
- 双指针找到满足条件的最大b
-
动态规划
- 先排序好
- dp[i][j][k],i表示前i种,j表示用j作为a的情况,k表示用k作为b的情况
- 状态转移:
-
不用当前i:dp[i][j][k] = dp[i-1][j][k]
-
用i作为a:更新 dp[i][j][k] 为 (i, b),b 从之前的 k 状态继承
- count[i] ≥ 3 且 j ≥ 3
-
i作为b:更新 dp[i][j][k] 为 (a, i),a 从之前的 j 状态继承
- count[i] ≥ 2 且 k ≥ 2
-
i 同时作为 a 和 b
- count[i] ≥ 5
- 更新 dp[i][j][k] 为 (i, i)
-
-
贪心+预处理
- 统计数量
- 预处理所有大于1和2的组合
- 从大到小尝试a,找到最大可行的b
function findFullHouse(n, maxSum, array) {
// 统计每种牌数量
const count = new Map();
for (let card of array) {
count.set(card, (count.get(card) || 0) + 1);
}
// 获取所有可能的牌面值
const values = Array.from(count.keys());
let bestA = 0;
let bestB = 0;
// 枚举三张相同的牌 a
for (let a of values) {
if (count.get(a) < 3) continue;
// 枚举两张相同的牌 b
for (let b of values) {
// 检查数量是否足够
if (a === b) {
if (count.get(a) < 5) continue;
} else {
if (count.get(b) < 2) continue;
}
// 检查和是否符合
const sum = 3 * a + 2 * b;
if (sum > maxSum) continue;
// 更新最大组合
if (a > bestA || (a === bestA && b > bestB)) {
bestA = a;
bestB = b;
}
}
}
return bestA === 0 ? [0, 0] : [bestA, bestB];
}
// 测试
const n = 9, maxSum = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1];
console.log(findFullHouse(n, maxSum, array)); // [8, 5]