此后如竟没有炬火 我便是唯一的光|

Day_Dreamer_D

园龄:3年6个月粉丝:3关注:16

2022-11-05 15:18阅读: 182评论: 0推荐: 1

accoders NOI #5047. 猜数游戏 题解

题目描述

Alice 和 Bob 玩游戏。

Alice 有一个 1 n 中的正整数 y。Bob 不知道这个数。

游戏中的每一轮,Bob 选一个正整数 x,并提问 Alice:y 是否大于等于 x?然后 Alice 需要回答是或否。

Alice 可以说至多一次谎。Bob 想要用尽量少的轮数确定 y,Alice 希望 Bob 用的次数尽量多。

假设双方除第一轮外均采用最优策略。

作为一只 Goodeat,你既不是 Alice,也不是 Bob。

但你需要求出,对每个 x=1,2,...,n,当 Bob 第一轮问 y 是否大于等于 x 且 Alice 第一轮回答了 是 的情况下,Bob 还需要多少轮能确定 y

(Alice 第一轮有可能说谎。)

思路

算法一

由于加入了说谎的机制,我们不能像原来的猜数游戏一样二分求解。

我们可以把每次询问看成一次覆盖,把“否”的一端覆盖掉,那么当一个区间被覆盖了两次,这个区间便不可能成为答案。

暴力搜索期望得分 20 分。

算法二

容易发现,去掉覆盖两次的区间之后,最后一定是形如 x0y1,再 z0

dpx,y,z 表示出现上面的序列时,还需要猜多少次。转移可以枚举 Bob 第一轮的分界位置。

时间复杂度 O(n4),期望得分 40 分。

算法三

考虑优化算法二。

我们注意到,在某个位置之前 Alice 回答大于更优,这个位置之后 Alice 回答小于更优。x,y 确定之后,对于不同 z,这一位置一定是单调的,于是我们可以线性算出这个位置并记录。

时间复杂度变为 O(n3),期望得分 70 分。

算法四

考虑 dp 的值域只有 O(logn),且关于 z 单调,于是我们改写状态,定义 fx,y,w 表示最大的 w 满足 dpx,y,zk

这样一来 f 的状态只有 O(n2logn) 种,而且转移方法类似。

期望得分 100 分。

代码

// ubsan: undefined
// accoders
/*
* Title: D. 猜数游戏
* Source: accoders NOI-2022NOIP A层联测20
* URL: http://47.92.197.167:5283/contest/275/problem/4
* Author: Steven_lzx
* Command: -std=c++23 -Wall -fno-ms-extensions
* Date: 2022.11.4
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2001,MOD=998244353,INF=0x3f3f3f3f;
int n,dp[20][MAXN][MAXN],res,i,j,k;
int main()
{
freopen("guess.in","r",stdin);
freopen("guess.out","w",stdout);
scanf("%d",&n);
for(i=0;i<20;i++)
for(j=0;j<=2000;j++)
for(k=0;k<=2000;k++)
dp[i][j][k]=-INF;
dp[0][0][1]=dp[0][1][0]=0;
dp[0][0][0]=1;
for(res=1;res<20;res++)
{
for(k=0;k<=n;k++)//k:mid
{
for(i=0;i<=n-k;i++)
{
j=dp[res-1][k][i]+dp[res-1][0][k];
if(j>=0)
{
j=min(j,n-k);
dp[res][k][i]=max(dp[res][k][i],j);
dp[res][k][j]=max(dp[res][k][j],i);
}
}
for(i=0;i<=k;i++)
{
j=k-i;
if(dp[res-1][i][j]>=0&&dp[res-1][j][i]>=0)
dp[res][k][min(dp[res-1][i][j],n-k)]=max(dp[res][k][min(dp[res-1][i][j],n-k)],min(dp[res-1][j][i],n-k));
}
for(i=n-k+1;i>=0;i--)
dp[res][k][i]=max(dp[res][k][i],dp[res][k][i+1]);
}
}
for(i=1;i<=n;i++)
{
j=0;
while(dp[j][n-i+1][i-1]<0)
j++;
printf("%d ",j);
}
putchar('\n');
fclose(stdin);
fclose(stdout);
return 0;
}

本文作者:Day_Dreamer_D

本文链接:https://www.cnblogs.com/2020gyk080/p/16860258.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Day_Dreamer_D  阅读(182)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起