题目:https://www.luogu.org/problemnew/show/P2593

发现三个连续牌的影响范围只有3、相同牌的影响范围只有1之后就可以dp了。

O(100^7)T飞。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int T,a[N];
bool dp[][N][N][N],flag;
int rdn()
{
int ret=;char ch=getchar();
while(ch>''||ch<'')ch=getchar();
while(ch>=''&&ch<='')(ret*=)+=ch-'',ch=getchar();
return ret;
}
int main()
{
T=rdn();
while(T--)
{
for(int i=;i<=;i++)a[i]=rdn();
for(int t=;t<=;t++)if(a[t]>=)
{
a[t]-=;
memset(dp[],,sizeof dp[]);
dp[][a[]][a[]][a[]]=;
for(int i=;i<=;i++)
{
flag=;int d=(i&);
memset(dp[!d],,sizeof dp[!d]);
for(int x=;x<=a[i-];x++)
for(int y=;y<=a[i-];y++)
for(int z=;z<=a[i];z++)
if(dp[d][x][y][z])
{
int lm=min(x,min(y,z));
for(int k=;k<=lm;k++)
{
dp[!d][y-k][z-k][a[i+]]|=(((x-k)%==)|((x-k)%==));
if(dp[!d][y-k][z-k][a[i+]])flag=;
}
}
if(!flag)break;
}
a[t]+=;
if(flag)break;
}
if(flag)printf("Yes\n");else printf("No\n");
}
return ;
}

如果不枚举对子在哪而是带一个0/1在状态里的话可以少乘一个100。

如果不无脑记录前两个位置而是仅记录前一个位置、用三连的时候调用一下上一层的话可以少乘一个100。

  这是因为最后要的只有dp[ ][0][0][0],所以保存很多“之前位置还不是0”的状态比较浪费。

不枚举用了几个三连,而是每层用“从开头降到这里”更新一下本层,就能把”在本层用较少的三连“包括在“用单个位置从之前层降下来”。这样可以少乘一个100。

  这里调了好久!必须是“从开头降到这里”,而不能是“从这里降到0”;因为从“这里”降的话需要判断本层是否可行,但这个可行是包括 i-2 的状态的,自己仅记录前一个位置的dp不能存下。如果是”从开头降到这里“的话,本层目前一定是可行的。

O(100^4)卡过。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int T,a[N];
bool dp[N][N][N][];
int rdn()
{
int ret=;char ch=getchar();
while(ch>''||ch<'')ch=getchar();
while(ch>=''&&ch<='')(ret*=)+=ch-'',ch=getchar();
return ret;
}
int main()
{
T=rdn();
while(T--)
{
memset(dp,,sizeof dp);
for(int i=;i<=;i++)a[i]=rdn();
dp[][][a[]][]=;
for(int i=;i<=;i++)
{
for(int x=a[i-];x>=;x--)
for(int y=a[i];y>=;y--)
{
dp[i][x][y][]|=dp[i][x][y+][]; dp[i][x][y][]|=dp[i][x][y+][];
dp[i][x][y][]|=dp[i][x][y+][]; dp[i][x][y][]|=dp[i][x][y+][];
dp[i][x][y][]|=dp[i][x][y+][];
//在a[i]变成各种y之后尝试一下从开头降到这里(先降后单个弄)
dp[i][x][y][]|=dp[i-][a[i]-y][x+a[i]-y][];
dp[i][x][y][]|=dp[i-][a[i]-y][x+a[i]-y][]; //在a[i]变成各种y之后尝试一下取完
// dp[i][x][0][0]|=dp[i-1][y][x+y][0];//不能&dp[i][x+y][y],因含义是i-2==0
// dp[i][x][0][1]|=dp[i-1][y][x+y][1];//不&的话会出错:0 3 0(原为2)
//因为从当前降到0的话,需要判断当前是否可行
//可是降还需要i-2的也许有值,与表示“当前可行”的dp冲突,即无法表示当前是否可行
//而“从开头”降的话,一定可行 //x之所以不是0,是因为这里用到dp[i-1][y][][]
if(!x)
{
dp[i+][y][a[i+]][]|=dp[i][][y][];
dp[i+][y][a[i+]][]|=dp[i][][y][];
}
// if(i<=3)
// {
// if(dp[i][x][y][0])printf("dp[%d][%d][%d][%d]=%d\n",i,x,y,0,dp[i][x][y][0]);
// if(dp[i][x][y][1])printf("dp[%d][%d][%d][%d]=%d\n",i,x,y,1,dp[i][x][y][1]);
// }
}
}
puts(dp[][][][]?"Yes":"No");
}
return ;
}

洛谷2593 [ZJOI2006]超级麻将——可行性dp的更多相关文章

  1. 洛谷 P2593 [ZJOI2006]超级麻将【dp】

    设f[i][j][k][0/1]表示选到i时,i-1选j张,i选k张,之前选的所有牌是否选择了对子 然后分情况讨论转移即可 #include<iostream> #include<c ...

  2. [bzoj1860 ZJOI2006] 超级麻将 (线性dp)

    传送门 Description Input 第一行一个整数N(N<=100),表示玩了N次超级麻将. 接下来N行,每行100个数a1..a100,描述每次玩牌手中各种牌的数量.ai表示数字为i的 ...

  3. LUOGU 2593 : [Zjoi2006] 超级麻将

    传送门 解题思路 直接爆搜全T..状态数太多了,所以我们考虑贪心+剪枝.贪心:先拿三个连着的,再拿四个一样的,再拿三个一样的,最后拿两个一样的这样的搜索顺序最优,两个的放最后是因为只要这样的一个,三个 ...

  4. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  5. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  6. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

  7. [ZJOI2006]超级麻将(可行性dp)

    题目描述 要判断某人是否胡牌,显然一个弱智的算法就行了,某中学信息学小组超级麻将迷想了想,决定将普通麻将改造成超级麻将. 所谓超级麻将没有了砣.索.万的区分,每种牌上的数字可以是1~100,而每种数字 ...

  8. [ZJOI2006]超级麻将

    题目描述 很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则: 普通麻将有砣.索.万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9 ...

  9. 洛谷P1880 石子合并(区间DP)(环形DP)

    To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...

随机推荐

  1. JS控制语句 编程练习 学生数据,分别是姓名、性别、年龄和年级,接下来呢,我们要利用JavaScript的知识挑出其中所有是大一的女生的的名字哦。

    编程练习 在一个大学的编程选修课班里,我们得到了一组参加该班级的学生数据,分别是姓名.性别.年龄和年级,接下来呢,我们要利用JavaScript的知识挑出其中所有是大一的女生的的名字哦. 学生信息如下 ...

  2. JS规则 自加一,自减一 ( ++和- -) 【mynum = mynum + 1;//等同于mynum++;】

    自加一,自减一 ( ++和- -) 算术操作符除了(+.-.*./)外,还有两个非常常用的操作符,自加一"++":自减一"--".首先来看一个例子: mynum ...

  3. Aria2配置文件-aria2.conf

    ##此部分主要分为几部分###1.文件保存#2.下载链接#3.进度保存#4.RPC相关#5.BT\PT下载相关 ##===================================#### 文件 ...

  4. No packages marked for update

    问题:用yum安装docker,更新yum存储时,报以下错误,导致yum坏了 [root@localhost yum.repos.d]# vi docker.repo [root@localhost ...

  5. BZOJ2741:[FOTILE模拟赛]L

    Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...

  6. PHP如何打造一个高可用高性能的网站呢?

    https://blog.csdn.net/jwq101666/article/details/80162245 1. 说到高可用的话要提一下redis,用过的都知道redis是一个具备数据库特征的n ...

  7. shell脚本实现读取一个文件中的某一列,并进行循环处理

    shell脚本实现读取一个文件中的某一列,并进行循环处理 1) for循环 #!bin/bash if [ ! -f "userlist.txt" ]; then echo &qu ...

  8. java日志管理 - slf4j+log4j2

    1 . 概述 1.1  日志框架实现 log4j是apache实现的一个开源日志组件: logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j ...

  9. ireport 无法打开问题

    打开时闪退 ,是因为jdk版本过高的原因:https://blog.csdn.net/aust_glj/article/details/52291240 相关软件下载地址: JasperReports ...

  10. <每日一题>题目6:二分查找

    #二分查找 ''' 1.end问题 2.44对应的end<start 找不到情况 3.返回值递归的情况 4,611,aim太大的情况 ''' l = [2,3,5,10,15,16,18,22, ...