P2668 斗地主 dp+深搜版
题目描述
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。
现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。
需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。
具体规则如下:
输入输出格式
输入格式:
第一行包含用空格隔开的2个正整数T和n,表示手牌的组数以及每组手牌的张数。
接下来T组数据,每组数据n行,每行一个非负整数对aibi表示一张牌,其中ai示牌的数码,bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。
输出格式:
共T行,每行一个整数,表示打光第i手牌的最少次数。
输入输出样例
1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
3
1 17
12 3
4 3
2 3
5 4
10 2
3 3
12 2
0 1
1 3
10 1
6 2
12 1
11 3
5 2
12 4
2 2
7 2
6
说明
样例1说明
共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。
对于不同的测试点, 我们约定手牌组数T与张数n的规模如下:
数据保证:所有的手牌都是随机生成的。
dp+深搜版
1 8
3 1
3 2
3 3
5 1
5 2
5 3
8 1
8 2
8 3
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=;
int T,n,p,hs,ans;
int dp[MAXN][MAXN][MAXN][MAXN],card_num[MAXN],happen[MAXN/];
int take_num[]={,,,};
int read(int & n)
{
char c='-';int x=;
while(c<''||c>'')c=getchar();
while(c>=''&&c<='')
{
x=x*+(c-);
c=getchar();
}
n=x;
}
int calc(int one,int two,int three,int four,int king)
{
if(king==)// 只有一张大小王
{
one++;// 看做单牌处理
king=;
}
if(king==)
return dp[four][three][two][one];
else
return min(dp[four][three][two][one+],dp[four][three][two][one]+);
}
void dfs(int now)//now是指已经操作的次数
{
if(now>ans)
return ;
memset(happen,,sizeof(happen));// 初始化
for(int i=;i<=;i++)
happen[card_num[i]]++;
ans=min(ans,now+calc(happen[],happen[],happen[],happen[],card_num[]));
for(int k=;k<=;k++)// 顺子
{
for(int i=;i<=;i++)
{
int j;
for(j=i;j<=&&card_num[j]>=k;j++)
{
card_num[j]-=k;
if(j-i+>=take_num[k])
dfs(now+);
}
for(j--;j>=i;j--)
card_num[j]+=k;
}
}
}
int main()
{
// freopen("landlords.in","r",stdin);
// freopen("landlords.out","w",stdout);
read(T);read(n);
memset(dp,,sizeof dp);
dp[][][][]=;
// dp[i][j][k][l]表示打出i套四张,j套三张,k套两站,l张单牌所需要的最少步数
for(int i=;i<=n;i++)//四张
for(int j=;j<=n;j++)//三张
for(int k=;k<=n;k++)//两张
for(int l=;l<=n;l++)//一张
if(i*+j*+k*+l*<=n)
{
dp[i][j][k][l]=i+j+k+l;//最坏的情况
if(i)
{
if(k>=)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k-][l]+);
// 四带一对对牌
if(l>=)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k][l-]+);
// 一对单牌
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-][j][k][l]+);
//啥都不带
}
if(j)
{
if(k)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k-][l]+);
// 3带对
if(l)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k][l-]+);
// 3带单
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j-][k][l]+);
// 什么都不带
}
if(k)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j][k-][l]+);
if(l)
dp[i][j][k][l]=min(dp[i][j][k][l],dp[i][j][k][l-]+);
}
while(T--)
{
memset(card_num,,sizeof(card_num));// 初始化
ans=n;
for(int i=;i<=n;i++)
{
read(p);read(hs);
if(p==)
card_num[]++;//大小王
else if(p==)
card_num[]++;// A
else card_num[p]++;
}
dfs();
printf("%d\n",ans);
}
return ;
}
P2668 斗地主 dp+深搜版的更多相关文章
- P2668 斗地主 贪心+深搜
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- 洛谷 P2392 kkksc03考前临时抱佛脚, dp / 深搜
题目链接 P2392 kkksc03考前临时抱佛脚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目 dp代码 #include <iostream> #includ ...
- ZOJ1100 状压DP +深搜
记得做过类似于这类题目是能够用组合数学方法来解决的,可惜淡忘了,也找不到了,看了网上的也有人提到过能够用组合公式解决,但是没人做,都是用了状压DP的方法,这个状压非常难讲清楚吧,推荐两篇 第一遍大体看 ...
- hdoj--3666--THE MATRIX PROBLEM(差分约束+SPFA深搜)
THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 深搜+DP剪枝 codevs 1047 邮票面值设计
codevs 1047 邮票面值设计 1999年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description ...
- 方格取数(多线程dp,深搜)
https://www.luogu.org/problem/P1004 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某 ...
- Luogu P2668 斗地主(NOIP2015)
还记得那道我只用特判得了30分的"斗地主"吗? 我今天脑抽打算把它改A掉.为什么不用这大好时光去干些更有意义的事 于是我就挖了这个坑. 题解: 题目链接:P2668 斗地主 本题就 ...
- ACM 海贼王之伟大航路(深搜剪枝)
"我是要成为海贼王的男人!" 路飞他们伟大航路行程的起点是罗格镇,终点是拉夫德鲁(那里藏匿着"唯一的大秘宝"--ONE PIECE).而航程中间,则是各式各样的 ...
- HDU 4597 Play Game(记忆化搜索,深搜)
题目 //传说中的记忆化搜索,好吧,就是用深搜//多做题吧,,这个解法是搜来的,蛮好理解的 //题目大意:给出两堆牌,只能从最上和最下取,然后两个人轮流取,都按照自己最优的策略,//问说第一个人对多的 ...
随机推荐
- html5视频播放器 一 (改写默认样式)
一个项目用到了html5视频播放器,于是就写了一个,走了很多坑,例如在chrome中加载视频出现加载异常等 先看看效果 是不是感觉换不错,以下是我播放器改写样式的布局. <!DOCTYPE ht ...
- mac idea快捷键(部分常用)
shift+F6重命名 shift+enter 换到下一行 shift+F8等同eclipse的f8跳到下一个断点,也等同eclipse的F7跳出函数 F8等同eclipse的f6跳到下一步F7等同e ...
- jQuery的DOM操作之捕获和设置
.html()--获取或设置目标元素内的全部内容,包括html的标签及属性在内: .text()--仅获取或设置目标元素内的文本内容. .val()--获取输入框的值: .attr()--获取或设置目 ...
- cocos2d-x中绘制3D图形--3D ToolKit for cocos2dx实现原理
首先:了解具体情况请看这里:https://github.com/wantnon2/3DToolKit-for-cocos2dx 在看代码之前,最好还是先把项目git下来执行一下demoproject ...
- C#如何设置窗体不能修改大小
找到FormBorderStyle设置为FixedDialog即可
- 【每日算法】排序算法总结(复杂度&稳定性)
一.插入排序:稳定,时间复杂度O(n^2) 想象你在打扑克牌,一開始左手是空的,接着右手開始从桌上摸牌,并将其插入到左手的一把牌中的正确位置上.为了找到这个正确位置,我们须要从右到左将它与手中的牌比較 ...
- Mac OS X 10.10, Eclipse+ADT真机调试代码时,Device Chooser中不显示真机的解决方式
Mac OS X 10.10的环境下.Eclipse+ADT,进行真机调试时,会出现一个问题. Device Chooser对话框里不显示真机设备,仅仅有又一次插拔数据线才干够. 经过測试.有两个暂时 ...
- P2P网贷中的4种理財业务模式
线上3种 直投标:线上理財人直接购买借款人的标.平台仅仅是起个"撮合"作用.收点借款人的服务费. 借款人不还钱,有的平台会帮"借款人" ...
- UVA10056 - What is the Probability ?(概率)
UVA10056 - What is the Probability ? (概率) 题目链接 题目大意:有n个人玩游戏,一直到一个人胜出之后游戏就能够结束,要不然就一直从第1个到第n个循环进行,没人一 ...
- aarch64-linux-gnu交叉编译Qt4.7.3
到 Qt 官网下载合适的 Qt 版本,地址:http://download.qt-project.org/archive/qt/ 1.环境搭建: 1.安装automake.libtool 和主机上的 ...