zoukankan      html  css  js  c++  java
  • [补档][NOIP2015] 斗地主

    [NOIP2015] 斗地主

    题目

    INPUT

    第一行包含用空格隔开的2个正整数Tn,表示手牌的组数以及每组手牌的张数。
    接下来T组数据,每组数据n行,每行一个非负整数对aibi表示一张牌,其中ai示牌的数码,bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。

    OUTPUT

    共T行,每行一个整数,表示打光第i手牌的最少次数。

    SAMPLE

    INPUT1

    1 8
    7 4
    8 4
    9 1
    10 4
    11 1
    5 1
    1 4
    1 1

    OUTPUT1

    3

    INPUT2

    1 17
    12 3
    4 3
    2 3
    5 4
    10 2
    3 3
    12 2
    0 1
    1 3
    10 1
    6 2
    12 1
    11 3
    5 2
    12 4
    2 2
    7 2

    OUTPUT2

    6

    解题报告

    考试时光顾着T3了,看到它时间根本不够= =,拿了小数据特判分走人= =
    显然是个暴搜模拟。
    首先,显然花色没用,大王小王也可以看做一样的牌,而且,出牌顺序显然没有影响。
    那么剩下的就很简单了,我们先出牌多的(正确性显然,因为这样答案一开始就不会很大,然后你可以用当前答案剪枝,因为已经不比当前答案优的解不可能推出最优解,这样,你可以利用较优的解减掉许多劣解,从而优化),并且,显然顺子一般来说要比带牌要优,那么剩下的就很简单了,注意一些出牌规则,不要像某些不会斗地主的小兄弟 (hww:喵喵喵?)一样= =
    要注意的是,顺子不一定越长越好,比如考虑这样一副牌:
    3 4 5 6 7 8 9 9 10 10 J J
    若是以越长越优的话,你会做出先打出顺子3~J,再单打9、10、J的决定,但显然打3~8的顺子加9~J的连对更优一些,所以我们在枚举顺子时,需要枚举所有可能的长度。
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 using namespace std;
      5 inline int read(){
      6     int sum(0);
      7     char ch(getchar());
      8     for(;ch<'0'||ch>'9';ch=getchar());
      9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
     10     return sum;
     11 }
     12 int size[30];
     13 int n,ans;
     14 inline int get_val(int x){
     15     if(x==1)
     16         return 12;
     17     if(x==2)
     18         return 13;
     19     if(x==0)
     20         return 14;
     21     return x-2;
     22 }
     23 inline int doit(){
     24     int tmp(0);
     25     int tp[6]={0};
     26     for(int i=1;i<=14;i++)
     27         tp[size[i]]++;
     28     while(tp[4]&&tp[2]>=2)
     29         tmp++,tp[4]--,tp[2]-=2;//四带俩对
     30     while(tp[4]&&tp[1]>=2)
     31         tmp++,tp[4]--,tp[1]-=2;//四带俩单
     32     while(tp[3]&&tp[2]>=1)
     33         tmp++,tp[3]--,tp[2]--;//三带二
     34     while(tp[3]&&tp[1]>=1)
     35         tmp++,tp[3]--,tp[1]--;//三带一
     36     tmp+=tp[1]+tp[2]+tp[3]+tp[4];
     37     return tmp;
     38 }
     39 inline int my_min(int a,int b){
     40     return a<b?a:b;
     41 }
     42 inline void dfs(int cnt){
     43     if(cnt>ans)
     44         return;
     45     int x(doit());
     46     ans=my_min(ans,cnt+x);
     47     for(int i=1;i<=11;i++){//三顺子
     48         int j;
     49         for(j=i;size[j]>=3&&j<=12;j++);
     50         if(j-i<2)
     51             continue;
     52         for(int k=j;k-i>=2;k--){
     53             for(int l=i;l<k;l++)
     54                 size[l]-=3;
     55             dfs(cnt+1);
     56             for(int l=i;l<k;l++)
     57                 size[l]+=3;
     58         }
     59     }
     60     for(int i=1;i<=10;i++){//连对
     61         int j;
     62         for(j=i;size[j]>=2&&j<=12;j++);
     63         if(j-i<3)
     64             continue;
     65         for(int k=j;k-i>=3;k--){
     66             for(int l=i;l<k;l++)
     67                 size[l]-=2;
     68             dfs(cnt+1);
     69             for(int l=i;l<k;l++)
     70                 size[l]+=2;
     71         }
     72     }
     73     for(int i=1;i<=8;i++){//顺子
     74         int j;
     75         for(j=i;size[j]>=1&&j<=12;j++);
     76         if(j-i<5)
     77             continue;
     78         for(int k=j;k-i>=5;k--){
     79             for(int l=i;l<k;l++)
     80                 size[l]--;
     81             dfs(cnt+1);
     82             for(int l=i;l<k;l++)
     83                 size[l]++;
     84         }
     85     }
     86 }
     87 inline int gg(){
     88 //  freopen("landlords.in","r",stdin);
     89 //  freopen("landlords.out","w",stdout);
     90     int T(read());
     91     n=read();
     92     while(T--){
     93         memset(size,0,sizeof(size));
     94         for(int i=1;i<=n;i++){
     95             int x(read()),y(read());
     96             size[get_val(x)]++;
     97         }
     98         ans=doit();
     99         dfs(0);
    100         printf("%d
    ",ans);
    101     }
    102     return 0;
    103 }
    104 int K(gg());
    105 int main(){;}
    View Code
    这一顿暴搜= =
  • 相关阅读:
    java 二分查找计算时间复杂度
    idea导出javadoc文档
    ext常用属性
    hibernate执行过程
    分布式架构初探
    web中几个context上下文的理解
    网上书城项目总结(servlet_jsp+javaBean)
    javaweb面试题01
    数据源和数据库连接池
    数据结构之必需知
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7277681.html
Copyright © 2011-2022 走看看