NOIP2015 斗地主


题目描述
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方
片的A 到K 加上大小王的共54 张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据
牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产
生影响。每一局游戏中,一副手牌由n 张牌组成。游戏者每次可以根据规定的牌型进行出
牌,首先打光自己的手牌一方取得游戏的胜利。现在,牛牛只想知道,对于自己的若干组
手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。需要注意的是,
本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:

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

 

solution

真是宇宙无敌大暴搜............(ps:反正我是对着测试点一个一个改过来的........)

不应该是状压:wxh和wq神犇都用状压,反正没改出来

牌型只有三种:1.顺子 2.带牌 3.单牌/对牌  (火箭也算对牌)

1.出牌的顺序不会影响答案

2.先搜顺子可以剪更多的枝,而且搜完顺子后,带牌和 单牌/对牌 可以用贪心求出

思路:

先 暴搜顺子  枚举  单/双/三顺子  左端点  右端点

之后用贪心求 其他牌型  (情况可能会很多.......)

我说说我遇到的坑点:

1.A可以当顺子

2.有不出顺子的出牌方式

3.4个2可以带2个王

4.注意贪心时 判断的优先级

5.4张牌 可以带两个相同的 单/对牌  例如:4个3 带4个2/带对2

这真是一个好题,不能浪费啊..

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<vector>
  5 #define ll long long
  6 #define mem(a,b) memset(a,b,sizeof(a))
  7 using namespace std;
  8 inline int minn(int a,int b){return a<b?a:b;}
  9 
 10 int t,n;
 11 int u,o,bushu;
 12 int a[15];
 13 int limit[4]={0,5,3,2};
 14 
 15 void clear()
 16 {
 17     mem(a,0);
 18 }
 19 
 20 bool check(int l,int size)
 21 {
 22     if(l+limit[size]-1>13)return 0;
 23     for(int i=l+limit[size]-1;i>=l;--i)
 24       if(a[i]<size)return 0;
 25     return 1;
 26 }
 27 
 28 void dfs(int now)
 29 {
 30     for(int size=1;size<=3;++size)
 31         for(int l=2;l<=13;++l)
 32         {
 33             if(!a[l])continue;
 34             if(!check(l,size))continue;
 35             for(int r=l+limit[size]-1;r<=13;++r)
 36             {
 37                 if(a[r]<size)break;
 38                 for(int k=l;k<=r;++k)
 39                   a[k]-=size;
 40                 dfs(now+1);
 41                 for(int k=l;k<=r;++k)
 42                   a[k]+=size;
 43             }
 44         }
 45     
 46     int temp[15];
 47     memcpy(temp,a,sizeof(temp));
 48     
 49     int num1=0,num2=0,num3=0,num4=0;
 50     for(int i=1;i<=13;++i)
 51     {
 52         if(temp[i]==1)++num1;
 53         else if(temp[i]==2)++num2;
 54         else if(temp[i]==3)++num3;
 55         else if(temp[i]==4)++num4;
 56     }
 57     if(num4)
 58       while(num4)
 59       {
 60             if(num1>=2){num1-=2;++now;--num4;continue;}
 61           if(num1==1)
 62           {
 63                 if(num2>=2){num2-=2;--num4;++now;continue;}
 64                 if(temp[14]){--num1;--temp[14];--num4;++now;continue;}
 65                 if(num2){--num2;--num4;++now;continue;}
 66             }
 67             if(num1==0)
 68             {
 69                 if(num2>=2){num2-=2;--num4;++now;continue;}
 70                 if(temp[14]==2){temp[14]=0;--num4;++now;continue;}
 71                 if(temp[14]==1)
 72                     if(num2){--temp[14];--num2;++num1;--num4;++now;continue;}
 73             }
 74             break;
 75         }
 76     if(num3)
 77       while(num3)
 78       {
 79             if(num1){--num1;--num3;++now;continue;}
 80             if(temp[14]){--temp[14];--num3;++now;continue;}
 81             if(num2){--num2;--num3;++now;continue;}
 82             break;
 83         }
 84     
 85     if(temp[14]==2){temp[14]=0;++now;}
 86     int qw=0;
 87     if(num4>=2)
 88         while(num4>=2){num4-=2;++qw;}//4带两个相同的对 
 89     
 90     bushu=minn(now+num1+num2+num3+num4+temp[14]+qw,bushu);
 91 }
 92 
 93 int main(){
 94     scanf("%d%d",&t,&n);
 95     while(t--)
 96     {
 97         clear();
 98         for(int i=1;i<=n;++i)
 99         {
100             scanf("%d%d",&u,&o);
101             if(!u)++a[14];
102             else
103               if(u==1)
104                 ++a[13];
105             else
106               ++a[u-1];
107         }
108         bushu=0x7fffffff;
109         dfs(0);
110         printf("%d\n",bushu);
111     }
112     //while(1);
113     return 0;
114 }
code

 

转载于:https://www.cnblogs.com/A-LEAF/p/7260032.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值