选择题

链接:

https://www.nowcoder.com/acm/contest/178/B

来源:牛客网

题目描述

有一道选择题,有 \(a,b,c,d\) 四个选项。

现在有 \(n\) 个人来做这题,第 \(i\) 个人有 \(p_{i,j}\) 的概率选第 \(j\) 个选项。

定义 \(cnt(x)\) 为选第 \(x\) 个选项的人数。

令 \(mx\) 为 \(cnt(x)\) 最大的 \(x\) (如果有多个\(cnt(x)\)最大的 \(x\),则取其中 \(x\) 最小的),

若\(cnt(mx) \le \lfloor\frac{n}{2}\rfloor\) ,则所有人得 \(0\) 分;

否则令 \(choice_i\) 表示第 \(i\) 个人选的选项,则第 \(i\) 人得\(w_{mx,choice_i}\)分

求每个人的期望得分。

输入描述:

第一行一个整数 \(n\) ,表示人数。

接下来 \(n\) 行,每行 \(4\) 个整数,其中第 \(i\) 行第 \(j\) 个数表示 \(p_{i,j}\) ,即在模 \(998244353\) 意义下第 \(i\) 个人选第 \(j\) 个选项的概率。

接下来 \(4\) 行,每行 \(4\) 个整数,第 \(i\) 行第 \(j\) 个数表示 \(w_{i,j}\) 。

输出描述:

共 \(n\) 行,第 \(i\) 行表示第 \(i\) 个人在模 \(998244353\) 意义下的期望得分。

备注:

全部的输入数据满足:

  • \(1 ≤ n ≤ 2000\)
  • $0 ≤ p_{i,j} < 998244353 (1 ≤ i ≤ n,1 ≤ j ≤ 4) $
  • \(\sum\limits_{j=1}^4 p_{i,j} \equiv 1 (\bmod 998244353)(1\le i \le n)\)

各个测试点的性质如下

测试点编号 n 特殊性质
\(1\) \(\le 2\)
\(2\) \(\le 10\) \(p_{i,3}=p_{i,4}=0,(1\le i \le n)\)
\(3\) \(\le 10\)
\(4,5\) \(\le 100\) \(p_{i,3}=p_{i,4}=0,(1\le i \le n)\)
\(6,7\) \(\le 100\) \(p_{i,4}=0(1\le i \le n)\)
\(8,9,10,11\) \(\le 100\)
\(12\sim20\) \(\le 2000\)

Solution

考试的时候打了55pts暴力,结果爆5了,原因竟然是出负数了没模正。。

枚举每个人选什么和最后结果是什么,然后算一下其他人的选择对这个结果的概率。

每次可以简单的\(n^2\)做\(dp\)

\(dp_{i,j}\)代表前\(i\)个人有\(j\)个选了的和

\(dp_{i,j}=dp_{i-1,j-1}p_{i,k}+dp_{i-1,j}(1-p_{i,k})\)

发现每次只是少了一个人不进行\(dp\)

可以先把所有人的\(dp\)搞出来,然后\(O(n)\)把人踢出来

具体的,设\(dp_{i}\)为\(i\)个人选了某选项的全集

枚举每个人时,显然有\(dp_i'=p_idp_{i-1}+(1-p_i)dp_i\)

那么回退时有\(dp_i=\frac{dp_i'-p_idp_{i-1}}{1-p_i}\)

注意压维了的话是存在顺序的,还要特判\(p_i=1\)


Code:

#include <cstdio>
#define ll long long
const int N=2e3+10;
const ll mod=998244353ll;
int n;
ll p[N][5],w[5][5],dp[N][5],inv[N][5],ans[N];
ll quickpow(ll d,ll k)
{
ll f=1;
d=(d%mod+mod)%mod;
while(k)
{
if(k&1) f=f*d%mod;
d=d*d%mod;
k>>=1;
}
return f;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=4;j++)
scanf("%lld",&p[i][j]),inv[i][j]=quickpow(1-p[i][j],mod-2);
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
scanf("%lld",&w[i][j]);
dp[0][1]=dp[0][2]=dp[0][3]=dp[0][4]=1;
for(int k=1;k<=4;k++)
for(int i=1;i<=n;i++)
{
ll p1=(1-p[i][k]),p2=p[i][k];
for(int j=n;j;j--)
dp[j][k]=(p2*dp[j-1][k]+p1*dp[j][k])%mod;
dp[0][k]=dp[0][k]*(1-p[i][k])%mod;
}
for(int i=1;i<=n;i++)//这个人
for(int j=1;j<=4;j++)//选啥
{
if(p[i][j]==0) continue;
for(int k=1;k<=4;k++)//结果是
{
if(w[k][j]==0) continue;
int flag=1,up=(n>>1)+1-(j==k);
ll sum=0;
if(p[i][k]==1) flag=0;
if(flag)
{
dp[0][k]=dp[0][k]*inv[i][k]%mod;
ll p2=p[i][k];
for(int l=1;l<up;l++)//退包
dp[l][k]=(dp[l][k]-p2*dp[l-1][k])%mod*inv[i][k]%mod;
for(int l=up;l<=n;l++)
{
dp[l][k]=(dp[l][k]-p2*dp[l-1][k])%mod*inv[i][k]%mod;
sum+=dp[l][k];
}
}
if(!flag)
{
for(int i=up+1;i<=n;i++)
sum+=dp[i][k];
}
sum%=mod;
(ans[i]+=w[k][j]*sum%mod*p[i][j])%=mod;
if(flag)
{
ll p1=(1-p[i][k]),p2=p[i][k];
for(int l=n;l;l--)
dp[l][k]=(dp[l][k]*p1+p2*dp[l-1][k])%mod;
dp[0][k]=dp[0][k]*(1-p[i][k])%mod;
}
}
}
for(int i=1;i<=n;i++)
printf("%lld\n",(ans[i]+mod)%mod);
return 0;
}

2018.10.21

nowcoder 提高组模拟赛 选择题 解题报告的更多相关文章

  1. nowcoder 提高组模拟赛 最长路 解题报告

    最长路 链接: https://www.nowcoder.com/acm/contest/178/A 来源:牛客网 题目描述 有一张 \(n\) 个点 \(m\) 条边的有向图,每条边上都带有一个字符 ...

  2. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  3. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  4. ZROI提高组模拟赛05总结

    ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...

  5. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

  6. NOIP2017提高组模拟赛 8(总结)

    NOIP2017提高组模拟赛 8(总结) 第一题 路径 在二维坐标平面里有N个整数点,Bessie要访问这N个点.刚开始Bessie在点(0,0)处. 每一步,Bessie可以走到上.下.左.右四个点 ...

  7. NOIP2017提高组模拟赛 9 (总结)

    NOIP2017提高组模拟赛 9 (总结) 第一题 星星 天空中有N(1≤N≤400)颗星,每颗星有一个唯一的坐标(x,y),(1≤x,y ≤N).请计算可以覆盖至少K(1≤K≤N)颗星的矩形的最小面 ...

  8. NOIP2017提高组模拟赛 7(总结)

    NOIP2017提高组模拟赛 7(总结) 第一题 斯诺克 考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示).我们把所有桌子边界上的整数点作为击球点(除了4个袋口),在每个击球点我们 ...

  9. NOIP2017提高组模拟赛5 (总结)

    NOIP2017提高组模拟赛5 (总结) 第一题 最远 奶牛们想建立一个新的城市.它们想建立一条长度为N (1 <= N <= 1,000,000)的 主线大街,然后建立K条 (2 < ...

随机推荐

  1. Learning Experience of Big Data:The First Day-Try to set up a network connection on my virtural machine

    After we install our virtual machine,the first thing we should do is to set up a network connection ...

  2. centos安装zabbix(server+agent)

    本文包含zabbix_server编译安装,zabbix_agent编译安装,中文字体修正 Mysql模板监控,Nginx模板监控,以及简单的web页面的使用 中文乱码的解决方案 zabbix乱码是字 ...

  3. 新手学习ARM,对片内ram、SDRAM、NOR FLASH和NAND FLASH启动这几个概念的理解

    片内的ram用来存储启动代码,在2440初始化sdram之前,代码就在片内ram中运行.片内ram装载的是norflash中的内容,即u-boot. uboot放在norflash里,nandflas ...

  4. PAT-B1032

    1032 挖掘机技术哪家强(20) 输入格式: 输入在第1行给出不超过10^5^的正整数N,即参赛人数.随后N行,每行给出一位参赛者的信息和成绩,包括其所代表的学校的编号(从1开始连续编号).及其比赛 ...

  5. (数据科学学习手札29)KNN分类的原理详解&Python与R实现

    一.简介 KNN(k-nearst neighbors,KNN)作为机器学习算法中的一种非常基本的算法,也正是因为其原理简单,被广泛应用于电影/音乐推荐等方面,即有些时候我们很难去建立确切的模型来描述 ...

  6. nginx error_page

    1. error_page语法 语法: error_page code [ code... ] [ = | =answer-code ] uri | @named_location 默认值: no 使 ...

  7. 2,理解JVM

      一.内存管理:   1,内存结构: 栈和堆区别,栈是连续内存区,一般是2M单位,堆是不连续的链表.受限于虚拟内存,new时分配 PC寄存器.java栈.堆.方法区.本地方法区.运行常量池 java ...

  8. 不用找了,比较全的signalR例子已经为你准备好了(2)---JqGrid 服务端刷新方式-注释详细-DEMO源码下载

    上次用客户端进行数据刷新的方式,和官方的Demo实现存在差异性,今天花了一点时间好好研究了一下后台时时刷新的方式.将写的代码重新update了一次,在这之前找过好多的资料,发现都没有找到好的例子,自己 ...

  9. Python-学习-项目1-即时标记-1

    买了一本Python入门,奈何看不下去,只能是先看后面的项目,看到那里不懂的时候在回去学习. 项目名字:即时标记 大致的意思就是把一个纯文本文件标记成自己想要的格式文件. 首先就是待处理文本,我找不到 ...

  10. 9.0 toast定位+WebDriverWait显示等待

    Toast  判断-----基本操作问题 首先基本操作,进入安卓市场的账号密码页面--- from appium import webdriver from selenium.webdriver.su ...