【UOJ #147】【NOIP 2015】斗地主

http://uoj.ac/problem/147

搜索时先枚举三顺子,双顺子和单顺子,然后贪心带牌和成三成双成单出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int in() {
    int k = 0, fh = 1; char c = getchar();
    for(; c < '0' || c > '9'; c = getchar())
        if (c == '-') fh = -1;
    for(; c >= '0' && c <= '9'; c = getchar())
        k = (k << 3) + (k << 1) + c - '0';
    return k * fh;
}
 
 
int a[20], c[5], n, ans;
 
int cal() {
    memset(c, 0, sizeof(c));
    for(int i = 0; i <= 13; ++i)
        ++c[a[i]];
    int ret = 0;
    while (c[4] && c[2] >= 2) --c[4], c[2] -= 2, ++ret;
    while (c[4] && c[1] >= 2) --c[4], c[1] -= 2, ++ret;
    while (c[3] && c[2]) --c[3], --c[2], ++ret;
    while (c[3] && c[1]) --c[3], --c[1], ++ret;
    return ret + c[4] + c[3] + c[2] + c[1];
}
 
void dfs(int step) {
    if (step >= ans) return;
    ans = min(ans, step + cal());
     
    int i, j, k, tail;
    j = 0;
    for(i = 2; i <= 13; ++i) {
        for(j = max(j, i); a[j] >= 3; ++j);
        for(tail = j; tail >= i + 2; --tail) {
            for(k = i; k < tail; ++k) a[k] -= 3;
            dfs(step + 1);
            for(k = i; k < tail; ++k) a[k] += 3;
        }
    }
     
    j = 0;
    for(i = 2; i <= 13; ++i) {
        for(j = max(j, i); a[j] >= 2; ++j);
        for(tail = j; tail >= i + 3; --tail) {
            for(k = i; k < tail; ++k) a[k] -= 2;
            dfs(step + 1);
            for(k = i; k < tail; ++k) a[k] += 2;
        }
    }
     
    j = 0;
    for(int i = 2; i <= 13; ++i) {
        for(j = max(j, i); a[j] >= 1; ++j);
        for(tail = j; tail >= i + 5; --tail) {
            for(k = i; k < tail; ++k) --a[k];
            dfs(step + 1);
            for(k = i; k < tail; ++k) ++a[k];
        }
    }
}
 
int main() {
    int T, color, num; T = in(); n = in();
    while (T--) {
        memset(a, 0, sizeof(a));
        for(int i = 1; i <= n; ++i) {
            num = in(); color = in();
            if (num == 1) num = 13;
            else if (num != 0) --num;
            ++a[num];
        }
        ans = cal();
        dfs(0);
        printf("%d\n", ans);
    }
    return 0;
}

QAQ

posted @   abclzr  阅读(192)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示