NOIP2015DAY1T3【斗地主】

牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、 方片的 A 到 K 加上大小王的共 54 张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10< J< Q< K< A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由 n 张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。

现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。

需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:


本题数据较水,请上https://vijos.org/p/1980测评

Input Format

输入文件名为 landlords.in。

第一行包含用空格隔开的2个正整数T,n,表示手牌的组数以及每组手牌的张数。

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

Output Format

输出文件名为 landlords.out。 共 T 行,每行一个整数,表示打光第i组手牌的最少次数。

【题解】

贪心 搜索(据说是有bug的但是是随机数据就能过)

先搜索顺子的每种出牌情况 (由于顺子不包括2,所以把整副牌的数字整体后移1变13,其余变为i-1,这样比较方便处理)

对于每种情况处理剩下的牌不用顺子最少几次出完(贪心)

贪心处理过程

1.四带两对 2.四带两张 3.四带一对 4.三代二 5.三带一 6.炸、三张、对子、单牌

王炸当做对牌处理


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include <vector>
#include <queue>
#include <map>
using namespace std;
int a[50],num[5],i,j,k,l,m,n,T,cnt,col,ans;
void dfs(int kk)
  {
  	if (kk>=ans) return;
  	

  	int i,j,k,l,tot=0;
  	memset(num,0,sizeof(num));
    for (i=0;i<=13;i++) num[a[i]]++;                                   
    for (;num[4]&&num[2]>1;num[4]--,num[2]-=2,tot++);      
    for (;num[4]&&num[1]>1;num[4]--,num[1]-=2,tot++);
    for (;num[4]&&num[2];num[4]--,num[2]--,tot++);
    for (;num[3]&&num[2];num[3]--,num[2]--,tot++);
    for (;num[3]&&num[1];num[3]--,num[1]--,tot++);
    tot+=(num[1]+num[2]+num[3]+num[4]);
	
	
	if (kk+tot<ans) ans=kk+tot;
	
	
	for (i=2;i<=13;i++)
	  {                    
         for (j=i;a[j]>=3;j++); 
         if(j-i>=2) 
		   {
             for (l=i+1;l<=j-1;l++)
			  {
                 for (k=i;k<=l;k++) a[k]-=3;
                 dfs(kk+1);
                 for (k=i;k<=l;k++) a[k]+=3;
              }
           }
      }
     
	 for (i=2;i<=13;i++)
	  {                    
         for (j=i;a[j]>=2;j++); 
         if(j-i>=3) 
		   {
             for (l=i+2;l<=j-1;l++)
			  {
                 for (k=i;k<=l;k++) a[k]-=2;
                 dfs(kk+1);
                 for (k=i;k<=l;k++) a[k]+=2;
              }
           }
      } 
     
     for (i=2;i<=13;i++)
	  {                    
         for (j=i;a[j]>=1;j++); 
         if(j-i>=5) 
		   {
             for (l=i+4;l<=j-1;l++)
			  {
                 for (k=i;k<=l;k++) a[k]-=1;
                 dfs(kk+1);
                 for (k=i;k<=l;k++) a[k]+=1;
              }
           }
      } 
  }
int main()
  {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
  	for (scanf("%d%d",&T,&n);T;T--)
	   {
	   	  memset(a,0,sizeof(a));
          int x,y;
          for (i=1;i<=n;i++) 
		    {
              scanf("%d%d",&cnt,&col);
              if(cnt==1) cnt=13; else if(cnt!=0) cnt--;a[cnt]++;
            }
          ans=1e9;dfs(0);
         printf("%d\n",ans);
	   } 
  } 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章