zoukankan      html  css  js  c++  java
  • 洛谷 P2668 斗地主

    题意简述

    读入一组牌,求最少需要多少次出牌可以将它们打光。

    题解思路

    暴力搜索+剪枝

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n, t, ax, bx, card[20], now, ans;
    void dfs();
    void shunzi(int x, int y);
    int main()
    {
        scanf("%d%d", &t, &n);
        for (int i = 1; i <= t; ++i)
        {
            ans = n;
            memset(card, 0, sizeof(card));
            for (int j = 1; j <= n; ++j)
            {
                scanf("%d%d", &ax, &bx);
                if (ax == 0)
                    ax = 16;
                if (ax < 3)
                    ax += 13;
                card[ax] ++;
            }
            dfs();
            printf("%d
    ", ans);
        }
    }
    void getstra(int x, int y)                        
    {
        for (int i = 3; i <= 15 - y; ++i)
        {
            int cnt = 0;
            for (int j = i; j <= 14; ++j)
                if (card[j] >= x)
                    cnt ++;
                else break;
            if (cnt >= y)
            {
                for (int j = i; j <= i + cnt - 1; ++j)
                    card[j] -= x;
                dfs();
                for (int j = i; j <= i + cnt - 1; ++j)
                    card[j] += x;
            }
        }
    }
    void dfs()
    {
        int cnt = 0;
        for (int i = 3; i <= 15; ++i)              
            cnt += (card[i] + 3) / 4;
        cnt += (card[16] + 1) / 2;
        if (now >= ans)                              
            return;
        ans = min(ans, cnt + now);
        now ++;
        getstra(3, 2);                                   
        getstra(2, 3);
        getstra(1, 5);
        for (int i = 3; i <= 15; ++i)                
        {
            if (card[i] >= 4)
            {
                card[i] -= 4;
                for (int j = 3; j <= 16; ++j)
                    for (int k = 3; k <= 16; ++k)
                    {
                        if ((j - i & i - k & k - j) && card[j] == card[k] && card[j] && card[k])
                        {
                            card[j] --;
                            card[k] --;
                            dfs();
                            if (card[j] && card[k])
                            {
                                card[j] --;
                                card[k] --;
                                dfs();
                                card[j] ++;
                                card[k] ++;
                            }
                            card[j] ++;
                            card[k] ++;
                        }
                    }
                card[i] += 4;
            }
        }
        for (int i = 3; i <= 15; ++i)            
        {
            if (card[i] >= 3)
            {
                card[i] -= 3;
                for (int j = 3; j <= 16; ++j)
                    if ((j - i) && card[j])
                    {
                        card[j] --;
                        dfs();
                        if (card[j])
                        {
                            card[j] --;
                            dfs();
                            card[j] ++;
                        }
                        card[j] ++;
                    }
                card[i] += 3;
            }
        }
        now --;
    }
    
  • 相关阅读:
    常见数据结构考题
    [转]Win7 系统安装VS2008没反应 点击安装一闪就没有反应 .
    [转]40个实习生最基本的规矩
    [转]C++中重载(overload)、覆盖(override)、隐藏(hide)的区别
    iPhone开源项目
    eclipse快捷键
    [转]cocos2d游戏开发,常用工具集合
    discuz中常用的一些东西
    抽象类与接口的区别
    Head.First设计模式学习笔记
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9429577.html
Copyright © 2011-2022 走看看