Description
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:
Input
第一行包含用空格隔开的2个正整数T,N,表示手牌的组数以及每组手牌的张数。
Output
共T行,每行一个整数,表示打光第T组手牌的最少次数。
Sample Input
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
Sample Output
HINT
共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方
题解
抓取有用信息:
出牌顺序不影响出牌次数。
30分算法:
1、$T≤100$,$n≤4$;
2、先特判掉三带一的情况,然后有几种不同点数的牌,答案就是几;注意两张王可以看成是相同点数;
3、时间复杂度$O(T*n)$
100分算法:
1、$T≤10$,$n≤23$;
2、既然出牌顺序不影响,那么不妨先出对子,包括单顺、双顺、三顺。具体就是直接暴力枚举每一个顺子,然后出掉,再枚举顺子,再出掉......
3、这样可以过吗?
一个顺子至少有$5$张牌,最多出$4$组顺子,递归层数很小;
然后在一组牌内可以产生$O(K^2)$个顺子,其中$K$表示能成为顺子组成部分的牌的种数,在这里$K=12$,然后这里的复杂度就是$O(K^8)$,看起来很大,其实实测完全可以跑出来;
4、然后就可以不考虑顺子了,那么对于剩下的牌,我们就只能一个一个或者一对一对或者一带一带地出,也就是说出牌次数与牌的点数无关了;
5、那么我们可以预处理一个$dp[a][b][c][d]$,表示手牌有"$d$张单牌,$c$个对子,$b$个三张,$a$个炸弹"的时候,把牌出完的最少次数。
6、可以动态规划求解,$joker$可以拿出单独讨论。
7、时间复杂度$O(n^4+T*K^8)$。
这道题还有数据增强版,就是多考虑几个条件,把牌拆开(详见代码中的$extra$)。
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int INF = ~0u>>;
const int lenth[] = {, , , }; int n, t;
int card[], f[][][][];
int ans; int getrest(int r1, int r2, int r3, int r4, int joker){
if (joker == ) r1++,joker--;
if (joker) return Min(f[r4][r3][r2][r1+], f[r4][r3][r2][r1]+);
return f[r4][r3][r2][r1];
}
void dfs(int t){
if (t >= ans) return;
int c[] = {};
for (int i = ; i <= ; i++) c[card[i]]++;
ans = Min(ans, t+getrest(c[], c[], c[], c[], card[]));
for (int len = ; len <= ; len++)
for (int i = ; i <= ; i++){
int j = i;
for (;j <= && card[j] >= len; j++){
card[j] -= len;
if (j-i+ >= lenth[len]) dfs(t+);
}
for (j--; j >= i; j--) card[j] += len;
}
}
void pre(){
memset(f, /, sizeof(f));
f[][][][] = ;
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
for (int p = ; p <= n; p++)
for (int q = ; q <= n; q++)
if (i*+j*+p*+q <= n)
{
f[i][j][p][q] = i+j+p+q;
if (i){
if (p >= ) f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p-][q]+);//四带两对
if (q >= ) f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p][q-]+);//四带二
if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p-][q+]);//extra:把对子拆成一个单的
f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p+][q]);//extra:把炸拆成两对
f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j+][p][q+]);//extra:把炸拆成单张和三张
f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p][q]+);//出炸
}
if (j){
if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p-][q]+);//三带一对
if (q) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p][q-]+);//三带一
f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p+][q+]);//extra:三拆成二+一
f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p][q]+);//直接出三张
}
if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p-][q]+);//直接出对子
if (q) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p][q-]+);//直接出单张
}
} int main(){
scanf("%d%d", &t, &n);
pre();
while (t--){
memset(card, , sizeof(card));
int a, b;
ans = n;
for (int i = ; i <= n; i++){
scanf("%d%d", &a, &b);
if (a == ) card[]++;
else card[a]++;
}
dfs();
printf("%d\n", ans);
}
return ;
}
[NOIp 2015]斗地主的更多相关文章
-
Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)
Luogu 2668 NOIP 2015 斗地主(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来 ...
-
基础算法(搜索):NOIP 2015 斗地主
Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3& ...
-
[BZOJ 4325][NOIP 2015] 斗地主
一道防AK好题 4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 820 Solved: 560[Submit] ...
-
[NOIP 2015] 斗地主 landlord
想起几个月之前的 noip2015-只会瞎搞-这道题骗了 30 分.T T 题目 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的 A 到 K 加上大小王的共 54 张牌 ...
-
noip 2015 斗地主 大爆搜!!!
反正肯定是大模拟 但是每一个可以出的牌都搜一定不是最优的 考虑最特殊的出牌方案:顺子(单,对,三) 每一种方案再加上暴力贪心打出剩下的牌的步数 #include<cstdio> #incl ...
-
洛谷 P2668 &; P2540 [ noip 2015 ] 斗地主 —— 搜索+贪心
题目:https://www.luogu.org/problemnew/show/P2668 https://www.luogu.org/problemnew/show/P2540 首先,如果没有 ...
-
4632 NOIP[2015] 运输计划
4632 NOIP[2015] 运输计划 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题解 题目描述 Description 公元 2044 ...
-
NOIP 2015
Prob.1 2015 神奇的幻方 模拟就好了.(这不是noip2017的初赛题么.)代码: #include<cstdio> #include<cstring> #inclu ...
-
[NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
随机推荐
-
nginx(一)
crul新浪微博的时候发现对面用的是nginx服务器,在虎扑足球(挺好的足球论坛)讨论世界杯也发现他们也用这nginx,联想到阿里的tengine也是基于nginx的,觉得有了解一下nginx的必要了 ...
-
oracle 复杂语句
select nvl(sum1,'0')as sum1,nvl(sum2,'0') as sum2,da2 from( select count(*) as sum1,substr(APPLY_DAT ...
-
Jquery 学习三
一.each语句 1.each语句的功能 在jQuery中,通过$函数获取的都是jQuery对象.通过测试可知,jQuery对象是一个类数组的特殊对象,其是DOM对象的集合.而each语句就是专门用于 ...
-
在Delphi中实现HexToStr函数和StrToHex函数
function TransChar(AChar: Char): Integer; begin '] then Result := Ord(AChar) - Ord(') else Result := ...
-
.NET Core实战项目之CMS 第九章 设计篇-白话架构设计
前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了.今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的<从零开始学架构>里面关于架构设 ...
-
RN android真机调试找不到设备
待完成…… 1.adb驱动安装 2.手机设置 3.添加adb_usb.ini文件
-
MySQL学习笔记Windows篇<;一>; Welcome to MySQL
MySQL安装完毕后没有图形化操作界面,图形化管理界面需要另行安装,个人比较喜欢Navicat,界面更像SQLserver: 此篇学习笔记所有操作均使用命令行中完成: 1.开启/停止服务 使用MySQ ...
-
Ubuntu/Debian 8 安装 Intel realsense 摄像头驱动
## Make Ubuntu/Debian Up-to-date1. sudo apt-get update && sudo apt-get upgrade && su ...
-
js对象及元素复制拷贝
1.数组及对象拷贝: 浅拷贝var b=$.extend(false,{},a);//对象浅拷贝 var a={aa:111,bb:{bb1:22}}; var b=$.extend(false,{} ...
-
UVa 11167 Monkeys in the Emei Mountain (最大流)
题意:雪雪是一只猴子.它在每天的 2:00 —— 9:00之间非常渴,所以在这个期间它必须喝掉2个单位的水.它可以多次喝水,只要它喝水的总量是2.它从不多喝,在一小时内他只能喝一个单位的水.所以它喝水 ...