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);
	   } 
  } 


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