NOIP2015 Day 1 T3 斗地主

来源:互联网 发布:淘宝卖家后台官网 编辑:程序博客网 时间:2024/05/19 23:59

首先我们把A存到a[12],把2存到a[13]中,这样处理顺子比较好处理

如果有四张的牌

首先我们肯定是带两张单牌比较优

然后是带两个对子优,之后是一个对子

因为对子组成顺子比单牌容易,所以优先搞单牌

三张的类似

然后枚举三种顺子

逐一枚举各种方案,去找最优解

因为顺子并不是越长越好的,打过斗地主的都知道吧

一个可行性剪枝是当现在的出牌的次数大于当前最优的方案就直接返回,不知道会快多少呢

每次的ans的初始值为23,因为最多的数据只有23张手牌,没有答案会比23大啦

#include<cstdio>#include<cstring>#include<iostream>using namespace std;int t, n;int a[17];int ans = 110;void init(){    memset(a, 0, sizeof(a));    ans = 110;}void dfs(int x){    if(x > ans) return;    int s1, s2, s3, s4;    s1 = s2 = s3 = s4 = 0;     //单 对    for(int i = 1; i <= 14; i++){        if(a[i] == 1)   s1++;        else if(a[i] == 2)  s2++;    }    //四带    for(int i = 1; i <= 14; i++){        if(a[i] == 4){            s4++;            if(s1 >= 2) s1 -= 2;            else if(s2 >= 2)    s2 -= 2;            else if(s2 >= 1)    s2--;        }    }    //三带    for(int i = 1; i <= 14; i++){        if(a[i] == 3){            s3++;            if(s1 >= 1) s1--;            else if(s2 >= 1)    s2--;        }    }    ans = min(ans, x+s1+s2+s3+s4);    int j;    //单顺子     for(int i = 1; i <= 8; i++){        for(j = i; j <= 12; j++){            a[j]--;            if(a[j] < 0)    break;            if(j-i >= 4)    dfs(x+1);        }        if(j == 13) j--;        while(j >= i)   a[j--]++;    }    //双顺子     for(int i = 1; i <= 10; i++){        for(j = i; j <= 12; j++){            a[j] -= 2;            if(a[j] < 0)    break;            if(j-i >= 2)    dfs(x+1);        }        if(j == 13) j--;        while(j >= i)   a[j--] += 2;    }    //三顺子     for(int i = 1;i <= 11; i++){        for(j = i; j <= 12; j++){            a[j] -= 3;            if(a[j] < 0)    break;            if(j-i >= 1)    dfs(x+1);        }        if(j == 13) j--;         while(j >= i)   a[j--] += 3;    }}int main(){
原创粉丝点击