Luogu 2668 [NOIP2015]斗地主
打牌技术不精,没有把$A$放在顺子里面搜,WA了好长时间。
盗用大佬的一张图:

当时自己搜的时候没有把四张牌拆成三带一等情况。
然后还有一点就是四张三张都出完之后直接数一数剩下的一张两张牌还要多少次出完就好了,没有必要浪费栈空间和递归深度去搜这些东西。(我就是这样T了好多次QωQ)。
要注意暴力算的前提就是一定要把之前的三张四张打完。
玄学复杂度。
代码很丑很长。
Code:
#include <cstdio>
#include <cstring>
using namespace std; const int N = ;
const int inf = << ; int testCase, n, cnt[N], ans; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMin(int &x, int y) {
if(y < x) x = y;
} void dfs(int rest, int stp) {
if(stp >= ans) return;
if(rest == ) {
chkMin(ans, stp);
return;
} /* for(int j, i = 3; i <= 14; i++) {
if(cnt[i] < 1) continue;
for(j = i; j <= 14; j++)
if(cnt[j] < 1) break;
j--;
if(j - i + 1 < 5) {
i = j;
continue;
}
for(int k = i; k <= j; k++) --cnt[k];
dfs(rest - (j - i + 1), stp + 1);
for(int k = i; k <= j; k++) ++cnt[k];
i = j;
} for(int j, i = 3; i <= 14; i++) {
if(cnt[i] < 2) continue;
for(j = i; j <= 14; j++)
if(cnt[j] < 2) break;
j--;
if(j - i + 1 < 3) {
i = j;
continue;
}
for(int k = i; k <= j; k++) cnt[k] -= 2;
dfs(rest - (j - i + 1) * 2, stp + 1);
for(int k = i; k <= j; k++) cnt[k] += 2;
i = j;
} for(int j, i = 3; i <= 14; i++) {
if(cnt[i] < 3) continue;
for(j = i; j <= 14; j++)
if(cnt[j] < 3) break;
j--;
if(j - i + 1 < 2) {
i = j;
continue;
}
for(int k = i; k <= j; k++) cnt[k] -= 3;
dfs(rest - (j - i + 1) * 3, stp + 1);
for(int k = i; k <= j; k++) cnt[k] += 3;
i = j;
} */ /* for(int j, k, i = 2; i <= 14; i++) {
if(cnt[i] < 4) continue;
for(j = 2; j <= 15; j++) {
if(j == i) continue;
if(cnt[j] > 1) {
for(k = 2; k <= 15; k++) {
if(k == i) continue;
if(cnt[k] > 1) {
cnt[i] -= 4, cnt[j] -= 2, cnt[k] -= 2;
dfs(rest - 8, stp + 1);
cnt[i] += 4, cnt[j] += 2, cnt[k] += 2;
}
}
}
}
} for(int j, k, i = 2; i <= 14; i++) {
if(cnt[i] < 4) continue;
for(j = 2; j <= 15; j++) {
if(j == i) continue;
if(cnt[j] > 0) {
for(k = 2; k <= 15; k++) {
if(k == i) continue;
if(cnt[k] > 0) {
cnt[i] -= 4, --cnt[j], --cnt[k];
dfs(rest - 6, stp + 1);
cnt[i] += 4, ++cnt[j], ++cnt[k];
}
}
}
}
} for(int i = 2; i <= 14; i++) {
if(cnt[i] < 4) continue;
cnt[i] -= 4;
dfs(rest - 4, stp + 1);
cnt[i] += 4;
} for(int j, i = 2; i <= 14; i++) {
if(cnt[i] < 3) continue;
for(j = 2; j <= 15; j++) {
if(j == i) continue;
if(cnt[j] > 1) {
cnt[i] -= 3, cnt[j] -= 2;
dfs(rest - 5, stp + 1);
cnt[i] += 3, cnt[j] += 2;
}
}
} for(int j, i = 2; i <= 14; i++) {
if(cnt[i] < 3) continue;
for(j = 2; j <= 15; j++) {
if(j == i) continue;
if(cnt[j] > 0) {
cnt[i] -= 3, --cnt[j];
dfs(rest - 4, stp + 1);
cnt[i] += 3, ++cnt[j];
}
}
} for(int i = 2; i <= 14; i++) {
if(cnt[i] < 3) continue;
cnt[i] -= 3;
dfs(rest - 3, stp + 1);
cnt[i] += 3;
} */ int len = ;
for(int i = ; i <= ; i++) {
if(cnt[i] == ) len = ;
else {
++len;
if(len >= ) {
for(int j = i; j >= i - len + ; j--) cnt[j]--;
dfs(rest - len, stp + );
for(int j = i; j >= i - len + ; j--) cnt[j]++;
}
}
} len = ;
for(int i = ; i <= ; i++) {
if(cnt[i] <= ) len = ;
else {
++len;
if(len >= ) {
for(int j = i; j >= i - len + ; j--) cnt[j] -= ;
dfs(rest - len * , stp + );
for(int j = i; j >= i - len + ; j--) cnt[j] += ;
}
}
} len = ;
for(int i = ; i <= ; i++) {
if(cnt[i] <= ) len = ;
else {
len++;
if(len >= ) {
for(int j = i; j >= i - len + ; j--) cnt[j] -= ;
dfs(rest - len * , stp + );
for(int j = i; j >= i - len + ; j--) cnt[j] += ;
}
}
} for(int i = ; i <= ; i++) {
if(cnt[i] <= ) {
if(cnt[i] <= ) continue;
cnt[i] -= ;
for(int j = ; j <= ; j++) {
if(j == i || cnt[j] == ) continue;
cnt[j]--;
dfs(rest - , stp + );
cnt[j]++;
}
for(int j = ; j <= ; j++) {
if(j == i || cnt[j] <= ) continue;
cnt[j] -= ;
dfs(rest - , stp + );
cnt[j] += ;
}
cnt[i] += ;
} else {
cnt[i] -= ;
for(int j = ; j <= ; j++) {
if(j == i || cnt[j] == ) continue;
cnt[j]--;
dfs(rest - , stp + );
cnt[j]++;
}
for(int j = ; j <= ; j++) {
if(j == i || cnt[j] <= ) continue;
cnt[j] -= ;
dfs(rest - , stp + );
cnt[j] += ;
}
cnt[i] += ; cnt[i] -= ;
for(int j = ; j <= ; j++) {
if(j == i || cnt[j] == ) continue;
cnt[j]--;
for(int k = ; k <= ; k++) {
if(k == j || cnt[k] == ) continue;
cnt[k]--;
dfs(rest - , stp + );
cnt[k]++;
}
cnt[j]++;
} for(int j = ; j <= ; j++) {
if(j == i || cnt[j] <= ) continue;
cnt[j] -= ;
for(int k = ; k <= ; k++) {
if(k == j || cnt[k] <= ) continue;
cnt[k] -= ;
dfs(rest - , stp + );
cnt[k] += ;
}
cnt[j] += ;
}
cnt[i] += ;
}
} int now = ;
for(int i = ; i <= ; i++)
if(cnt[i]) ++now; chkMin(ans, stp + now);
} int main() {
// freopen("Sample.txt", "r", stdin);
// freopen("testdata.in", "r", stdin);
// freopen("my.txt", "w", stdout); read(testCase), read(n);
for(; testCase--; ) {
memset(cnt, , sizeof(cnt)); for(int x, y, i = ; i <= n; i++) {
read(x), read(y);
if(x == ) cnt[]++;
else {
if(x == ) cnt[]++;
else cnt[x]++;
}
} ans = inf;
dfs(n, ); printf("%d\n", ans);
}
return ;
}
Luogu 2668 [NOIP2015]斗地主的更多相关文章
- Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)
Luogu 2668 NOIP 2015 斗地主(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来 ...
- NOIP2015斗地主[DFS 贪心]
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- BZOJ 4325: NOIP2015 斗地主
4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 684 Solved: 456[Submit][Status] ...
- NOIP2015 斗地主(搜索+剪枝)
4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 270 Solved: 192[Submit][Status] ...
- [补档][NOIP2015] 斗地主
[NOIP2015] 斗地主 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=2106 INPUT 第一行包含用空格隔开的2个正整数Tn,表示手 ...
- LOJ2422 NOIP2015 斗地主 【搜索+贪心】*
LOJ2422 NOIP2015 斗地主 LINK 题目大意很简单,就是问你斗地主的一分手牌最少多少次出完 然后我们发现对于一种手牌状态,不考虑顺子的情况是可以贪心做掉的 然后我们直接枚举一下顺子出牌 ...
- 【BZOJ4325】NOIP2015 斗地主 搜索+剪枝
[BZOJ4325]NOIP2015 斗地主 Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗 ...
- 2106. [NOIP2015] 斗地主
2106. [NOIP2015] 斗地主 ★★★☆ 输入文件:landlords.in 输出文件:landlords.out 简单对比 时间限制:2 s 内存限制:1025 M ...
- NOIP2015斗地主题解 7.30考试
问题 B: NOIP2015 斗地主 时间限制: 3 Sec 内存限制: 1024 MB 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共 ...
随机推荐
- P4388 付公主的矩形(gcd+欧拉函数)
P4388 付公主的矩形 前置芝士 \(gcd\)与欧拉函数 要求对其应用于性质比较熟,否则建议左转百度 思路 有\(n×m\)的矩阵,题目要求对角线经过的格子有\(N\)个, 设函数\(f(x,y) ...
- 算法(Algorithms)第4版 练习 1.3.37
package com.qiusongde.creative; import com.qiusongde.Queue; import edu.princeton.cs.algs4.StdOut; pu ...
- 现有exe转为服务_方式01
1.安装X.exe服务: ...>路径\X.exe /install 2.卸载X.exe服务: ...>路径\X.exe /uninstall 3.开始运行XX(程序是X.exe,服务名是 ...
- HDU 4714 Tree2cycle:贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4714 题意: 给你一棵树,添加和删除一条边的代价都是1.问你将这棵树变成一个环的最小代价. 题解: 贪 ...
- PHP基于单例模式编写PDO类的方法
一.单例模式简介 简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务: 二.为什么要使用PHP单例模式? 1.php的应用主要在于数据库应用, 所以一个应用中会存在 ...
- 雅礼集训 2017 Day2 水箱 可并堆
题目描述 给出一个长度为 n 宽度为 1 ,高度无限的水箱,有 n−1 个挡板将其分为 n 个 1 - 1 的小格,然后向每个小格中注水,水如果超过挡板就会溢出到挡板的另一边,这里的水是满足物理定律 ...
- Hihocoder1662 : 查找三阶幻方([Offer收割]编程练习赛40)(暴力)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个N x M的矩阵,请你数一数其中有多少个3 x 3的子矩阵可以构成三阶幻方? 如果3 x 3的矩阵中每一行.每一列 ...
- OSS阿里云文件上传 demo。
所需jar包: aliyun-openservices-1.2.3.jar jdom-1.1.jar commons-codec-1.4.jar commons-logging-1.1.1.jar g ...
- bzoj 2823: [AHOI2012]信号塔 最小圆覆盖
题目大意: 给定n个点,求面积最小的园覆盖所有点.其中\(n \leq 10^6\) 题解: 恩... 刚拿到这道题的时候... 什么???最小圆覆盖不是\(O(n^3)\)的随机增量算法吗????? ...
- 【LeetCode】137. Single Number II
题目: Given an array of integers, every element appears three times except for one. Find that single o ...