zoukankan      html  css  js  c++  java
  • Luogu 2668 [NOIP2015]斗地主

    打牌技术不精,没有把$A$放在顺子里面搜,WA了好长时间。

    盗用大佬的一张图:

    当时自己搜的时候没有把四张牌拆成三带一等情况。

    然后还有一点就是四张三张都出完之后直接数一数剩下的一张两张牌还要多少次出完就好了,没有必要浪费栈空间和递归深度去搜这些东西。(我就是这样T了好多次QωQ)。

    要注意暴力算的前提就是一定要把之前的三张四张打完。

    玄学复杂度。

    代码很丑很长。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 20;
    const int inf = 1 << 30;
    
    int testCase, n, cnt[N], ans;
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMin(int &x, int y) {
        if(y < x) x = y;
    }
    
    void dfs(int rest, int stp) {    
        if(stp >= ans) return;
        if(rest == 0) {
            chkMin(ans, stp);
            return;
        }
        
    /*    for(int j, i = 3; i <= 14; i++) {
            if(cnt[i] < 1) continue; 
            for(j = i; j <= 14; j++)
                if(cnt[j] < 1) break;
            j--;
            if(j - i + 1 < 5) {
                i = j;
                continue;
            }
            for(int k = i; k <= j; k++) --cnt[k];
            dfs(rest - (j - i + 1), stp + 1);
            for(int k = i; k <= j; k++) ++cnt[k];
            i = j;
        }    
        
        for(int j, i = 3; i <= 14; i++) {
            if(cnt[i] < 2) continue; 
            for(j = i; j <= 14; j++)
                if(cnt[j] < 2) break;
            j--;
            if(j - i + 1 < 3) {
                i = j;
                continue;
            }
            for(int k = i; k <= j; k++) cnt[k] -= 2;
            dfs(rest - (j - i + 1) * 2, stp + 1);
            for(int k = i; k <= j; k++) cnt[k] += 2;
            i = j;
        }
        
        for(int j, i = 3; i <= 14; i++) {
            if(cnt[i] < 3) continue; 
            for(j = i; j <= 14; j++)
                if(cnt[j] < 3) break;
            j--;
            if(j - i + 1 < 2) {
                i = j;
                continue;
            }
            for(int k = i; k <= j; k++) cnt[k] -= 3;
            dfs(rest - (j - i + 1) * 3, stp + 1);
            for(int k = i; k <= j; k++) cnt[k] += 3;
            i = j;
        }  */
    
    /*    for(int j, k, i = 2; i <= 14; i++) {
            if(cnt[i] < 4) continue;
            for(j = 2; j <= 15; j++) {
                if(j == i) continue;
                if(cnt[j] > 1) {
                    for(k = 2; k <= 15; k++) {
                        if(k == i) continue;
                        if(cnt[k] > 1) {
                            cnt[i] -= 4, cnt[j] -= 2, cnt[k] -= 2;
                            dfs(rest - 8, stp + 1);
                            cnt[i] += 4, cnt[j] += 2, cnt[k] += 2;
                        }
                    }
                }
            }
        }
    
        for(int j, k, i = 2; i <= 14; i++) {
            if(cnt[i] < 4) continue;
            for(j = 2; j <= 15; j++) {
                if(j == i) continue;
                if(cnt[j] > 0) {
                    for(k = 2; k <= 15; k++) {
                        if(k == i) continue;
                        if(cnt[k] > 0) {
                            cnt[i] -= 4, --cnt[j], --cnt[k];
                            dfs(rest - 6, stp + 1);
                            cnt[i] += 4, ++cnt[j], ++cnt[k];
                        }
                    }
                }
            }
        }
    
        for(int i = 2; i <= 14; i++) {
            if(cnt[i] < 4) continue;
            cnt[i] -= 4;
            dfs(rest - 4, stp + 1);
            cnt[i] += 4;
        }
    
        for(int j, i = 2; i <= 14; i++) {
            if(cnt[i] < 3) continue;
            for(j = 2; j <= 15; j++) {
                if(j == i) continue;
                if(cnt[j] > 1) {
                    cnt[i] -= 3, cnt[j] -= 2;
                    dfs(rest - 5, stp + 1);
                    cnt[i] += 3, cnt[j] += 2;   
                }
            }
        }
    
        for(int j, i = 2; i <= 14; i++) {
            if(cnt[i] < 3) continue;
            for(j = 2; j <= 15; j++) {
                if(j == i) continue;
                if(cnt[j] > 0) {
                    cnt[i] -= 3, --cnt[j];
                    dfs(rest - 4, stp + 1);
                    cnt[i] += 3, ++cnt[j];  
                }
            }       
        }
    
        for(int i = 2; i <= 14; i++) {
            if(cnt[i] < 3) continue;
            cnt[i] -= 3;
            dfs(rest - 3, stp + 1);
            cnt[i] += 3;
        }   */
        
        int len = 0;
        for(int i = 3; i <= 14; i++) {
            if(cnt[i] == 0) len = 0;
            else {
                ++len;
                if(len >= 5) {
                    for(int j = i; j >= i - len + 1; j--) cnt[j]--;
                    dfs(rest - len, stp + 1);
                    for(int j = i; j >= i - len + 1; j--) cnt[j]++;
                }
            }
        }
        
        len = 0;
        for(int i = 3; i <= 14; i++) {
            if(cnt[i] <= 1) len = 0;
            else {
                ++len;
                if(len >= 3) {
                    for(int j = i; j >= i - len + 1; j--) cnt[j] -= 2;
                    dfs(rest - len * 2, stp + 1);
                    for(int j = i; j >= i - len + 1; j--) cnt[j] += 2; 
                }
            }
        }
        
        len = 0;
        for(int i = 3; i <= 14; i++) {
            if(cnt[i] <= 2) len = 0;
            else {
                len++;
                if(len >= 2) {
                    for(int j = i; j >= i - len + 1; j--) cnt[j] -= 3;
                    dfs(rest - len * 3, stp + 1);
                    for(int j = i; j >= i - len + 1; j--) cnt[j] += 3;
                }
            }
        }
        
        for(int i = 2; i <= 14; i++) {
            if(cnt[i] <= 3) {
                if(cnt[i] <= 2) continue;
                cnt[i] -= 3;
                for(int j = 2; j <= 15; j++) {
                    if(j == i || cnt[j] == 0) continue;
                    cnt[j]--;
                    dfs(rest - 4, stp + 1);
                    cnt[j]++;
                }
                for(int j = 2; j <= 15; j++) {
                    if(j == i || cnt[j] <= 1) continue;
                    cnt[j] -= 2;
                    dfs(rest - 5, stp + 1);
                    cnt[j] += 2;
                }
                cnt[i] += 3;
            } else {
                cnt[i] -= 3;
                for(int j = 2; j <= 15; j++) {
                    if(j == i || cnt[j] == 0) continue;
                    cnt[j]--;
                    dfs(rest - 4, stp + 1);
                    cnt[j]++;
                }
                for(int j = 2; j <= 15; j++) {
                    if(j == i || cnt[j] <= 1) continue;
                    cnt[j] -= 2;
                    dfs(rest - 5, stp + 1);
                    cnt[j] += 2;
                }
                cnt[i] += 3;
                
                cnt[i] -= 4;
                for(int j = 2; j <= 15; j++) {
                    if(j == i || cnt[j] == 0) continue;
                    cnt[j]--;
                    for(int k = 2; k <= 15; k++) {
                        if(k == j || cnt[k] == 0) continue;
                        cnt[k]--;
                        dfs(rest - 6, stp + 1);
                        cnt[k]++;
                    }
                    cnt[j]++;
                }
                
                for(int j = 2; j <= 14; j++) {
                    if(j == i || cnt[j] <= 1) continue;
                    cnt[j] -= 2;
                    for(int k = 2; k <= 14; k++) {
                        if(k == j || cnt[k] <= 1) continue;
                        cnt[k] -= 2;
                        dfs(rest - 8, stp + 1);
                        cnt[k] += 2;
                    }
                    cnt[j] += 2;
                }
                cnt[i] += 4;
            }
        }
        
        int now = 0;
        for(int i = 2; i <= 15; i++)
            if(cnt[i]) ++now;
        
        chkMin(ans, stp + now);
    }
    
    int main() {
    //    freopen("Sample.txt", "r", stdin);
    //    freopen("testdata.in", "r", stdin);
    //    freopen("my.txt", "w", stdout);
    
        read(testCase), read(n);
        for(; testCase--; ) {
            memset(cnt, 0, sizeof(cnt));
    
            for(int x, y, i = 1; i <= n; i++) {
                read(x), read(y);
                if(x == 0) cnt[15]++; 
                else {
                    if(x == 1) cnt[14]++;
                    else cnt[x]++;
                }
            }
    
            ans = inf;
            dfs(n, 0);
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

  • 相关阅读:
    HDU 1201 18岁生日 【日期】
    单点登录cas常见问题(二)
    IntelliJ IDEA 15和Maven创建Java Web项目
    ExpandableListView的使用以及信息的高亮显示
    基于RTP的h.264视频传输系统设计(一)
    RocketMQ 消息队列单机部署及使用
    使用MySQL Workbench进行数据库设计——MySQL Workbench用法总结
    从JVM的角度看JAVA代码--代码优化
    Ajax系列之四:问题总结
    使用css打造形形色色的形状!
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9667834.html
Copyright © 2011-2022 走看看