[六省联考2017]分手是祝愿 题解(期望dp)
题目描述
B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态,下标为从 1 到 n 的正整数。
每个灯有两个状态亮和灭,我们用 1 来表示这个灯是亮的,用 0 表示这个灯是灭的,游戏的目标是使所有灯都灭掉。
但是当操作第 i 个开关时,所有编号为 i 的约数(包括 1 和 i)的灯的状态都会被改变,即从亮变成灭,或者是从灭变成亮。
B 君发现这个游戏很难,于是想到了这样的一个策略,每次等概率随机操作一个开关,直到所有灯都灭掉。
这个策略需要的操作次数很多,B 君想到这样的一个优化。如果当前局面,可以通过操作小于等于 k 个开关使所有灯都灭掉,那么他将不再随机,直接选择操作次数最小的操作方法(这个策略显然小于等于 k 步)操作这些开关。
B 君想知道按照这个策略(也就是先随机操作,最后小于等于 k 步,使用操作次数最小的操作方法)的操作次数的期望。
这个期望可能很大,但是 B 君发现这个期望乘以 n 的阶乘一定是整数,所以他只需要知道这个整数对 100003 取模之后的结果。
$Solution:$
好神啊。
首先考虑怎么做才是最优策略,不难得出一个猜想:从右向左操作,能关就关。
感性理解一下,编号小的肯定无法控制编号大的,而每个编号进行操作所影响的集合也是一定的(与它目前的状态无关)。既然编号大的且亮着的迟早都要按,而且影响也是确定的,那不如先按它确定了状态来进行接下来的处理。
另外,这样显然每个灯最多操作一次,所以最优步数一定不大于n。
对于每个状态,最优策略是唯一确定的,那么我们就可以用最优策略下的操作数来代表每个状态。
如果在$i$状态进行正确的操作,$i$就会变成$i-1$。反之,如果操作不正确,它就会变成$i+1$。
对随机的部分,设$dp[i]$为从$i$到$i-1$所需的期望步数。
根据之前的推论,不难得到:$dp[i]=1 \times \frac{i}{n} + \frac{n-i}{n} \times (dp[i]+dp[i+1]+1)$
按对了一步跳过去,按错了回到$i+1$,还需要$dp[i+1]+dp[i]+1$才能跳到$i-1$。
化简得到$dp[i]=\frac{(n-i)dp[i+1]+n}{i}$,先求个$\sum$,再和采取最优策略部分的步数拼一下就是答案。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e5+5;
typedef long long ll;
const ll mod=1e5+3;
int n,K,a[N];
vector<int> fact[N];
ll fac=1,ans,dp[N];
ll qpow(ll x,ll y)
{
ll res=1;x=x%mod;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
} void ini()
{
for(int x=1;x<=n;x++)
{
fac*=1LL*x,fac%=mod;
for(int i=1;i*i<=x;i++)
{
if(x%i)continue;
if(i*i==x)fact[x].push_back(i);
else fact[x].push_back(i),fact[x].push_back(x/i);
}
}
} int main()
{
scanf("%d%d",&n,&K);
ini();
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int step=0;
for(int i=n;i;i--)
{
if(!a[i])continue;
step++;
for(int j=0;j<fact[i].size();j++)
a[fact[i][j]]^=1;
}
if(step<=K)
{
printf("%lld\n",1LL*step*fac%mod);
return 0;
}
for(int i=n;i>K;i--)
{
ll inv=qpow(i,mod-2);
dp[i]=(1LL*(n-i)*dp[i+1]%mod+n%mod)%mod;
(dp[i]*=inv)%=mod;
}
for(int i=K+1;i<=step;i++)
(ans+=dp[i])%=mod;
(ans+=K)%=mod;
(ans*=fac)%=mod;
cout<<ans<<endl;
return 0;
}
[六省联考2017]分手是祝愿 题解(期望dp)的更多相关文章
- luoguP3750 [六省联考2017]分手是祝愿 概率期望DP + 贪心
...........真的神状态了,没办法去想的状态................... 考试的时候选择$50$分贪心+$15$分状压吧,别的点就放弃算了........ 令$f[i]$表示从最小步 ...
- BZOJ4872 [六省联考2017]分手是祝愿 【期望dp】
题目 Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态,下标为 从 1 ...
- 洛谷P3750 [六省联考2017]分手是祝愿(期望dp)
传送门 嗯……概率期望这东西太神了…… 先考虑一下最佳方案,肯定是从大到小亮的就灭(这个仔细想一想应该就能发现) 那么直接一遍枚举就能$O(nlogn)$把这个东西给搞出来 然后考虑期望dp,设$f[ ...
- [六省联考2017]分手是祝愿(期望+DP)
题解 很容易想出来最优策略是什么. 就是从n到1看到开着的灯就把它关了 我们预处理出当前状态把灯全部关闭后的最少步数cnt 然后我们的主人公就要瞎按... 设dp[i]代表当前状态最优解为i步时走到d ...
- 洛谷 P3750 - [六省联考2017]分手是祝愿(期望 dp)
题面传送门 首先我们需注意到这样一个性质:那就是对于任何一种状态,将其变为全 \(0\) 所用的最小步数的方案是唯一的--考虑编号为 \(n\) 的灯,显然如果它原本是暗着的就不用管它了,如果它是亮着 ...
- BZOJ 4872 luogu P3750 [六省联考2017]分手是祝愿
4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description ...
- bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿
http://www.lydsy.com/JudgeOnline/problem.php?id=4872 一种最优解是 从大到小灯有亮的就灭掉 最优解是唯一的,且关灯的顺序没有影响 最优解 对每个开关 ...
- [BZOJ4872][六省联考2017]分手是祝愿(期望DP)
4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 516 Solved: 342[Submit][Statu ...
- [BZOJ4872][六省联考2017]分手是祝愿
BZOJ Luogu sol 首先发现肯定有解,又因为每个位置至多操作一次,所以最优解一定是在\([0,n]\)之间 有一种可以在\(O(\sum_{i=1}^{n}\lfloor\frac{n}{i ...
随机推荐
- MIS(管理信息系统)
MIS 管理信息系统(Management Information System,简称MIS) 是一个以人为主导,利用计算机硬件.软件.网络通信设备以及其他办公设备,进行信息的收集.传输.加工.储存. ...
- signer information does not match signer information of other classes in the same package
报错日志: java.lang.SecurityException: class "org.bouncycastle.asn1.ASN1ObjectIdentifier"'s si ...
- element table组件懒加载
directives : { loadmore : { bind(el, binding) { const selectWrap = el.querySelector('.el-table__body ...
- [CSP-S模拟测试]:涂色游戏(DP+组合数+矩阵快速幂)
题目描述 小$A$和小$B$在做游戏.他们找到了一个$n$行$m$列呈网格状的画板.小$A$拿出了$p$支不同颜色的画笔,开始在上面涂色.看到小$A$涂好的画板,小$B$觉得颜色太单调了,于是把画板擦 ...
- QTP笔记--检查点、ChildObjects方法
一.自带检查点函数 '最后一个参数为timeout,单位是毫秒 Browser( "SAP NetWeaver Portal" ).Page( "SAP NetWeave ...
- 题解 P1017 【进制转换】
我赶jio这个题难道是让我们写快写? 不管了,赶紧把咕咕咕了一万年的题解写出来. 这个题就是考察负进制和在mod意义下的除法运算的基础运算. (其实也没多大问题) 首先我们先假设一个原始数据\(num ...
- (66) c# async await
1.使用 async await 2.返回值 static void Main(string[] args) { Program p = new Program(); Console.WriteLin ...
- delphi 在代码中 添加 TO-DO 并且 管理
TO-DO List是一项非常好用的功能.采用她可以让我们很清楚的了解以前完成了那些任务,还有哪些任务需要做,由谁负责完成,是不是比较紧急的任务等.今天来不及完成的,明天上班就可以很快的找到任务所在的 ...
- HBase–RegionServer宕机恢复原理
Region Server宕机总述 HBase一个很大的特色是扩展性极其友好,可以通过简单地加机器实现集群规模的线性扩展,而且机器的配置并不需要太好,通过大量廉价机器代替价格昂贵的高性能机器.但也正因 ...
- mysql中@ROW的使用
一.从test02表中查询每个uid最早登录的前2天 表如下图所示: select * from (select uid,day, @ROW := END rn, @uuid:=uid from (s ...