https://zhaotiensn.blog.luogu.org/solution-p4459

从上面的题解中可以找到样例解释,并了解两个人的思维方式。

A和B能从“不知道”到“知道”的唯一情况,就是根据已知条件(也就是已经说的”不知道“次数)排除手上数的所有其它合法拆分方案。

那么,设dp[i][j][k]表示,两个数分别为i,j,当前已经说了k次不知道,这个数是否能确定(也就是某方知道了答案)。

那么有两种转移

dp[i][j][k]|=dp[i][j][k-2]  一轮之前就已经知道了这轮肯定也知道。

对于B: dp[i-s][j+s][k-1]在s取遍所有合法取值时,只有s=0是false,其余全为true。也就是i+j的所有其它合法拆分方案在说了k-2次不知道后,A都应该说知道答案了,唯独这种方案仍不知道,那么B就肯定可以确定这个数了。

对于A: 同理,将i*j拆分即可。

考虑什么情况下满足题设条件,即说了t次”不知道“后双方都知道答案了。

那么就是dp[i][j][t-1]为false而dp[i][j][t]为true。但是这样只能保证已经有一方已知答案,同时还要保证的是另一方当这方说”知道了“之后也知道了答案,而说之前还不知道,这需要另一个类似的暴力拆分解决。

所以我们分别模拟两人的思维,后期每个点大约跑几分钟。

 #include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int s,t;
bool flag,f[N][N][];
char a[]; bool chk1(int x,int y,int t){
int num=x*y,len=sqrt(x*y),x1=,y1=,cnt=;
rep(i,s,len)
if(num%i== && ((!f[i][num/i][t-])||(!t)))
x1=i,y1=num/i,cnt++;
if(cnt== && x1==x && y1==y) return ; else return ;
} bool chk2(int x,int y,int t){
int num=x+y,len=(x+y)/,x1=,y1=,cnt=;
rep(i,s,len)
if((!f[i][num-i][t-])||(!t))
x1=i,y1=num-i,cnt++;
if(cnt== && x1==x && y1==y) return ; else return ;
} bool chk3(int x,int y,int t){
int num=x*y,len=sqrt(x*y),x1=,y1=,cnt=;
rep(i,s,len)
if(num%i== && (f[i][num/i][t]&&(t<||(!f[i][num/i][t-]))))
x1=i,y1=num/i,++cnt;
if(cnt== && x1==x && y1==y) return ; else return ;
} bool chk4(int x,int y,int t){
int num=x+y,len=(x+y)/,x1=,y1=,cnt=;
rep(i,s,len)
if(f[i][num-i][t]&&(t<||(!f[i][num-i][t-])))
x1=i,y1=num-i,++cnt;
if(cnt== && x1==x && y1==y) return ; else return ;
} int main(){
freopen("guess.in","r",stdin);
freopen("guess.out","w",stdout);
scanf("%d",&s); scanf("%s",a+); scanf("%d",&t);
if (a[]=='A') flag=; else flag=;
rep(i,,t){
flag^=;
rep(j,s,) rep(k,s,){
if(i>=)f[j][k][i]=f[j][k][i-];
f[j][k][i]|=flag?chk1(j,k,i):chk2(j,k,i);
}
}
int sum=*s,x=,y=;
while (){
rep(i,s,sum/){
x=i; y=sum-i; flag=f[x][y][t];
if (!flag) continue;
rep(j,,t-) if(f[x][y][j]){ flag=false; break; }
if (!flag) continue;
if(((t&)&&a[]=='A')||((!(t&))&&a[]=='B')) flag=chk3(x,y,t); else flag=chk4(x,y,t);
if (!flag) continue;
printf("%d %d\n",x,y); return ;
}
sum++;
}
return ;
}

[luogu4459][BJOI2018]双人猜数游戏(DP)的更多相关文章

  1. [BJOI2018]双人猜数游戏

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

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

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

  3. 【洛谷4459】[BJOI2018] 双人猜数游戏(动态规划)

    点此看题面 大致题意: 一直有两个数\(m,n\),已知\(s\le m\le n\),且\(Alice\)和\(Bob\)二个"最强大佬"各知道\(mn\)和\(m+n\).每轮 ...

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

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

  5. 1536 不一样的猜数游戏 dp思维 + 找规律

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1536 首先,要知道值为n的答案,则可以这么去想,知道值为n - 1的答案 ...

  6. BZOJ 2222: [Cqoi2006]猜数游戏【神奇的做法,傻逼题,猜结论】

    2222: [Cqoi2006]猜数游戏 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 260[Submit][Status ...

  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. VC++的全局变量(转)

    全局变量一般这样定义:1.在一类的.cpp中定义 int myInt;然后再在要用到的地方的.cpp里extern int myInt:这样就可以用了. 2.在stdafx.cpp中加入:int my ...

  2. 程序移植到AUTOCAD2013笔记

    1:需要引用acmgd.dll acdbmgd.dll,AcCoreMdg.dll, accui.dll 四个dll 2: 2010下的的acmgd.dll被拆分为acmgd.dll和AcCoreMd ...

  3. verilog中wire与reg类型的区别

    每次写verilog代码时都会考虑把一个变量是设置为wire类型还是reg类型,因此把网上找到的一些关于这方面的资料整理了一下,方便以后查找. wire表示直通,即只要输入有变化,输出马上无条件地反映 ...

  4. java 判断上传文件大小

    /** * 判断文件大小 * * @param file * 文件 * @param size * 限制大小 * @param unit * 限制单位(B,K,M,G) * @return */ pu ...

  5. [转载]如何在C++03中模拟C++11的右值引用std::move特性

    本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...

  6. Spark RDD 窄依赖研究

    1.. 简介 spark从RDD依赖上来说分为窄依赖和宽依赖. 其中可以这样区分是哪种依赖:当父RDD的一个partition被子RDD的多个partitions引用到的时候则说明是宽依赖,否则为窄依 ...

  7. Python列表(list)

    序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. 此外,Python已经内置确定序列的长度以及确定最大和最小的元素 ...

  8. 基于RESTful API 设计用户权限控制

    RESTful简述 本文是基于RESTful描述的,需要你对这个有初步的了解. RESTful是什么? Representational State Transfer,简称REST,是Roy Fiel ...

  9. git —— 分支

    git中每一个分支相当于一个时间线 并列且相互平行 控制用指针控制~ 1.第一种创建命令: $ git branch 分支名称 —— 创建分支 $ git checkout 分支名称 —— 切换分支 ...

  10. 前端程序员必知的30个Chrome扩展-[转载]

    谷歌Chrome浏览器是网络上可用的最好浏览器之一,并且自2011年11月超越了Firefox浏览器之后,已经成为了互联网上占主导地位的浏览器.今天,HTML5中国与大家分享一些实用的谷歌Chrome ...