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

    题意:给你一手牌,要你按照斗地主的规则以最少的出牌次数把这手牌打完传送门

    题解:

    搜索

    搜索顺子,然后开桶打光散牌,记录最小答案即可

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #define ll long long 
    using namespace std;
    
    int gi() {
      char ch=getchar(); int x=0;
      while(ch<'0' || ch>'9') ch=getchar();
      while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
      return x;
    }
    
    int T,n,ans;
    int num[10],cnt[20];
    
    int others() {
      int tot=0;
      memset(num,0,sizeof(num));
      for(int i=1; i<=14; i++) num[cnt[i]]++;
      while(num[4] && num[2]>=2) tot++,num[4]--,num[2]-=2;
      while(num[4] && num[1]>=2) tot++,num[4]--,num[1]-=2;
      while(num[4] && num[2]>=1) tot++,num[4]--,num[2]--;
      while(num[3] && num[2]>=1) tot++,num[3]--,num[2]--;
      while(num[3] && num[1]>=1) tot++,num[3]--,num[1]--;
      return tot+num[1]+num[2]+num[3]+num[4];
    }
    
    void dfs(int k) {
      if(k>=ans) return;
      ans=min(ans,others()+k);//在当前出牌阶段强行把牌打光的次数  
      for(int i=3; i<=13; i++) {
        if(cnt[i]>=3) {
          int j=i;
          while(cnt[j]>=3 && j<=14) j++;
          if(j-i>=2) {
            for(int l=i+1; l<j; l++) {
              for(int p=i; p<=l; p++) cnt[p]-=3;
              dfs(k+1);
              for(int p=i; p<=l; p++) cnt[p]+=3;
            }
          }
        }
      }
      for(int i=3; i<=12; i++) {
        if(cnt[i]>=2) {
          int j=i;
          while(cnt[j]>=2 && j<=14) j++;
          if(j-i>=3) {
            for(int l=i+2; l<j; l++) {
              for(int p=i; p<=l; p++) cnt[p]-=2;
              dfs(k+1);
              for(int p=i; p<=l; p++) cnt[p]+=2;
            }
          }
        }
      }
      for(int i=3; i<=10; i++) {
        if(cnt[i]>=1) {
          int j=i;
          while(cnt[j]>=1 && j<=14) j++;
          if(j-i>=5) {
            for(int l=i+4; l<j; l++) {
              for(int p=i; p<=l; p++) cnt[p]--;
              dfs(k+1);
              for(int p=i; p<=l; p++) cnt[p]++;
            }
          }
        }
      }
    }
    
    int main() {
      T=gi(),n=gi();
      while(T--) {
        ans=1<<30;
        memset(cnt,0,sizeof(cnt));
        for(int i=1; i<=n; i++) {
          int numb=gi(),col=gi();
          if(numb==1) numb=14;//A变成14
          if(numb==0) numb=1;//大小王变成1
          cnt[numb]++;
        }
        dfs(0);
        printf("%d
    ", ans);
      }
      return 0;
    }
    
  • 相关阅读:
    Nexus入门指南(图文)[转]
    java注解[转]
    JS设置IE可信站点及ActiveX设置
    ExtJS 4 树
    SQL大全
    基于Spring aop 和JAVA注解方式添加日志
    Excle自动增长序号
    VS 生成后事件
    Oracle命令分解之正则表达式搜索(一)
    Oracle命令分解之……SOUNDEX
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7638254.html
Copyright © 2011-2022 走看看