点此看题面

大致题意: 一直有两个数\(m,n\),已知\(s\le m\le n\),且\(Alice\)和\(Bob\)二个“最强大佬”各知道\(mn\)和\(m+n\)。每轮依次询问二人是否知道\(m\)和\(n\)是多少,求构造一对合法的\(m,n\),使他们两个共说恰好\(t\)次不知道。

手玩样例

这题看起来真是神仙,差不多就是两个神仙人不停地说不知道,然后突然就知道了。。。

所以我们要来手(解)玩(释)一下样例。

这里先不讲如何求答案,就来讲一下这答案为什么可以,以样例\(1\)为例。

最后得到的\(m,n\)分别为\(6,10\),也就是说\(Alice\)和\(Bob\)分别得到的是\(60\)和\(16\)。

那我们来模拟一下他们的思路:

第\(1\)轮

  • \(Bob\):对于\(Bob\)来说,\(16=5+11=6+10=7+9=8+8\),在没有任何信息的情况下,无法排除任何一种答案。
  • \(Alice\):对于\(Alice\)来说,\(60=5*12=6*10\),这两种情况下的和分别为\(17\)和\(16\),而如果\(Bob\)得到的是\(17\)或\(16\),都不能一次确定答案,因此\(Alice\)也无法排除任何一种答案。

第\(2\)轮

  • \(Bob\):上面提到过的\(4\)种情况,所对应的积分别为\(55,60,63,64\),而除了\(60\)以外,其余\(3\)种情况在\(5\le m\le n\)的情况下都只有一种分解方式,所以\(Alice\)可以直接确定。而\(Alice\)依然不知道,因此可以将这\(3\)种情况排除,就得出答案为\(6,10\)。
  • \(Alice\):同理,在\(Bob\)确定之后也可以通过类似的方式确定。

动态规划

我们可以考虑用动态规划+剪枝来做这题。

设\(f_{i,j,k}\)表示已经说过\(i\)次不知道,且两个数分别为\(j,k\)时是否能确定

显然,对于每个人的询问是隔两次出现一次的。

而一个人如果上次被询问时已经知道答案了,下一次询问自然也知道。

于是可以推出第一个转移式:\(f_{i,j,k}=f_{i-2,j,k}\)。

而光这一个式子显然是不够的(废话),考虑上面手玩样例的过程,我们可以发现,以\(Alice\)为例,如果与\(j,k\)乘积相等的其他情况(设为\(x,y\))都可以使\(f_{i-1,x,y}=1\)(即如果是这种情况,上一次询问时另一个人就能得出答案),且\(f_{i-1,j,k}=0\),就可以排除其他所有情况,确定\(f_{i,j,k}=1\)。

对于\(Bob\)同理。

这样就可以通过动态规划来预处理出\(f\)数组了。

求出答案

考虑到题目首先要求\(m+n\)最小,其次要求\(m\)最小,因此考虑先枚举\(m+n\),然后枚举\(m\)。

于是就变成了判断一对\(m,n\)是否符合题目要求。

首先,由于要恰好说\(t\)次不知道,因此我们要保证对于任一\(i<t\),\(f_{i,m,n}=0\)。

然后,还要特判一下\(f_{t+1,m,n}\)是否确定,即判断此时的情况是否唯一,不然依然无法做到恰好说\(t\)次不知道。

这与之前动态规划的第二种转移方式的代码类似,具体实现详见代码。

代码

不知道不知道出了什么问题提答交不上去。。。只能直接交代码了(反正也跑得挺快,能\(AC\))。

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 15
#define V 300
using namespace std;
int n,t,k,f[N+5][V+5][V+5];char s[10];
I bool CheckA_Init(CI t,CI x,CI y)//预处理时对Alice的判断
{
RI i,v=x*y,lim=sqrt(v),flag=0;for(i=k;i<=lim;++i)//枚举情况
{
if(v%i||(t&&f[t-1][i][v/i])) continue;//如果x*y不是i的倍数(即不存在这种情况),或者这种情况会使f[t-1][i][v/i]=1,就说明不符合条件
if(i^x||flag) return false;flag=1;//如果符合条件的答案不为x,y,或有多种答案符合条件,说明不合法,返回false
}return flag;//若只有x,y未确定,则可将其确定
}
I bool CheckB_Init(CI t,CI x,CI y)//预处理时对Bob的判断
{
RI i,v=x+y,lim=v>>1,flag=0;for(i=k;i<=lim;++i)//枚举情况
{
if(t&&f[t-1][i][v-i]) continue;//如果这种情况会使f[t-1][i][v-i]=1,就说明不符合条件
if(i^x||flag) return false;flag=1;//如果符合条件的答案不为x,y,或有多种答案符合条件,说明不合法,返回false
}return flag;//若只有x,y未确定,则可将其确定
}
I bool CheckA_Answer(CI t,CI x,CI y)//求答案时对Alice的判断
{
RI i,v=x*y,lim=sqrt(v),flag=0;for(i=k;i<=lim;++i)//枚举情况
{
if(v%i||!f[t][i][v/i]||(t>=2&&f[t-2][i][v/i])) continue;//如果x*y不是i的倍数(即不存在这种情况),或者这种情况无法确定f[t][i][v/i]=1,或者在上一轮已经可以确定f[t-2][i][v/i]=1,就说明不符合条件
if(i^x||flag) return false;flag=1;//如果符合条件的答案不为x,y,或有多种答案符合条件,说明不合法,返回false
}return flag;//若只有x,y合法,则可确定f[t+1][m][n]为1
}
I bool CheckB_Answer(CI t,CI x,CI y)//求答案时对Bob的判断
{
RI i,v=x+y,lim=v>>1,flag=0;for(i=k;i<=lim;++i)//枚举情况
{
if(!f[t][i][v-i]||(t>=2&&f[t-2][i][v-i])) continue;//如果这种情况无法确定f[t][i][v-i]=1,或者在上一轮已经可以确定f[t-2][i][v-i]=1,就说明不符合条件
if(i^x||flag) return false;flag=1;//如果符合条件的答案不为x,y,或有多种答案符合条件,说明不合法,返回false
}return flag;//若只有x,y合法,则可确定f[t+1][m][n]为1
}
int main()
{
RI i,j,l,STO,ORZ,op,flag;scanf("%d%s%d",&k,&s,&n),t=s[0]=='B';//读入数据
for(i=0,op=t;i<=n;++i,op^=1) for(STO=k;STO<=V;++STO) for(ORZ=k;ORZ<=V;++ORZ)
f[i][STO][ORZ]=i>=2&&f[i-2][STO][ORZ]?1:(op?CheckB_Init(i,STO,ORZ):CheckA_Init(i,STO,ORZ));//动态规划预处理
for(i=k<<1;;++i) for(j=1;j<=(i>>1);++j)//枚举答案
{
for(flag=f[n][STO=j][ORZ=i-j],l=0;l^n&&flag;++l) f[l][STO][ORZ]&&(flag=0);if(!flag) continue;//若存在更早的情况,说明无法做到恰好t个,跳过
if(!((n&1?!t:t)?CheckA_Answer(n,STO,ORZ):CheckB_Answer(n,STO,ORZ))) continue;//特判
return printf("%d %d",STO,ORZ),0;//输出答案并结束程序
}return 0;
}

【洛谷4459】[BJOI2018] 双人猜数游戏(动态规划)的更多相关文章

  1. 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)

    题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...

  2. [BJOI2018]双人猜数游戏

    题解: 彻彻底底的思维题???还是挺难的.. 首先连样例解释都没给..没看题解搞了很久 大概就是 一个人要根据另一个人的决策来猜数 可以去看洛谷那篇题解的解释 然后我们用$f[A/B][i][j][k ...

  3. [luogu4459][BJOI2018]双人猜数游戏(DP)

    https://zhaotiensn.blog.luogu.org/solution-p4459 从上面的题解中可以找到样例解释,并了解两个人的思维方式. A和B能从“不知道”到“知道”的唯一情况,就 ...

  4. 【洛谷P1005】矩阵取数游戏

    矩阵取数游戏 题目链接 每行分别跑一趟区间DP即可 这道题区间DP是非常裸的,按套路来即可 但是很毒瘤的是需要高精度, “我王境泽就是爆零,从这跳下去,也不会用__int128的!” #include ...

  5. 【LOJ】#2511. 「BJOI2018」双人猜数游戏

    题解 设\(f[p][a][b]\)表示询问了\(p\)次,答案是\(a,b\)是否会被猜出来 然后判断如果\(p = 1\) 第一个问的\(Alice\),那么\([s,\sqrt{nm}]\)约数 ...

  6. 洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game

    洛谷 2953 [USACO09OPEN]牛的数字游戏Cow Digit Game 题目描述 Bessie is playing a number game against Farmer John, ...

  7. 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)

    1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...

  8. usaco 猜数游戏

    Description 为了提高智商,锻炼思维能力,奶牛设计了一个猜数游戏.游戏开始前,贝西会在牛棚后面摆上N个数字.所有数字排成一条直线,按次序从1到N编号.每个数字在1到10^9之间,没有两个数字 ...

  9. (一)Python之猜数游戏

    猜数游戏由简如深的编码学习过程: 3次机会: print('------------------我爱鱼C工作室------------------')count=0while count < 3 ...

随机推荐

  1. ZPL打印机命令解释

    个人备忘: 1.装驱动,装驱动要装对应的ZPL或者EPL版本,目前发现GK888T无需选择,直接装GK888T即可,其他机型未知. 2.标签设计,文本部分用SimSun-ExtB字体,变量内容部分用Z ...

  2. CPU的CAS操作

    https://blog.csdn.net/qq_35492857/article/details/78471032 https://www.cnblogs.com/gdjdsjh/p/5076815 ...

  3. windows环境搭建禅道项目管理工具

    zentao官网的几个网址 http://www.zentao.net/ http://www.zentao.net/article-view-79863.html   搭建环境需要下载两个文件 1) ...

  4. C++的静态Static

    类的静态数据成员是属于类(即与类关联)而不属于类的每个对象(不与类的每个对象关联)(相当于该静态对象在所有的类对象中共享.),所以初始化方法与一般的变量不同,需要在类的构造函数之外进行初始化. 类的静 ...

  5. python学习之可变不可变

    在python的数据类型中,整数.字符串.元组是不可变的:而列表.字典是可变的.所以不用C的思维来修改一个整数,它相当于重新定义了一个整数(原来的被覆盖掉了),名字和原来一样,但与前面的同名变量没有一 ...

  6. (转)在 VMware 中安装 HMC

    在 VMware 中安装 HMC 原文:http://blog.csdn.net/ccie38499/article/details/14123493 http://www.54it.top/arch ...

  7. php-fpm 进程在云服务器cpu分配不均匀

    8核的云服务器,开了200个php-fpm进程,用top命令查看  大部分进程都在cpu 0 上跑着,导致其他cpu 负载很低,cpu分配不均匀: 使用shell 解决问题: 列出所有php-fpm ...

  8. Datastructure

    时间复杂度的计算 计算最坏情况下执行语句的次数(含有n) 去掉常数项, 只保留最高项, 去掉系数 最后的结果一般是1, logn, n, nlogn, n^2, 2^n, n!, n^n 时间复杂度所 ...

  9. C#数字图像处理算法学习笔记(二)--点运算与直方图

    C#数字图像处理算法学习笔记(二)--点运算与直方图 在数字图像处理中,点运算是一种简单而重要的技术.点运算只是根据对象的像素的输入灰度值来决定像素的输出灰度值的图像处理运算.它有时也被称为对比度增强 ...

  10. VueJs组件prop验证简单理解

    今天看了vuejs的组件,看到了prop组件,主要作用是在传入数据的时候对传入的值做判断,写了个小例子. <div id="app"> <my-child :nu ...