表示每次看见期望的题就很懵逼。。。

但是这题感觉还是值得一做,有可借鉴之处

要是下面这段文字格式不一样的话(虽然好像的确不一样,我也不知道为什么,是直接从代码里面复制出来的,因为我一般都是习惯在代码里面敲注释。。。

还是比较妙的。

首先有一个贪心的最优策略,由于每盏灯最多开一次(两次就相当于没开),并且都只能影响它以及它之前的,

也就是只能被后面的影响,所以从后往前遍历,如果一盏灯还是开的话,那我们就必须关掉它,

不然就没人能关掉它了,于是这样我们可以得到对于初始状态的最优操作次数,

这个时候,由于操作先后顺序不对答案造成影响,因此我们可以直接用这个最优操作次数来描述一个状态,

而一开始的局面求出的最优操作次数t就是我们当前的状态,

设f[i]为状态为i时的期望,因此我们要求的就是f[t],

由于每盏灯都相当于是相互独立的,因此我们有:

$f[i]=(i/n) * f[i-1] + (n-i)/n * f[i+1] + 1;$

解释:
  当最优操作为i次时,我们有i/n的概率操作到这i盏灯中的一盏,这时状态变为f[i-1],

  而剩下的(n-i)/n的概率就会操作到其他的灯,于是这会让状态变坏,变为f[i+1],

  最后还要加上当前操作(正是这次操作导致了那些概率的产生)

  但是我们发现,这样的话,f[i]就需要用f[i-1]和f[i+1]来推了,显然不太好,
  于是考虑对式子进行化简:
方法一:(我的推倒)
   令$g[i]=f[i] - f[i-1]$;

  于是直接对原式进行化简,如出现形如f[i] - f[i-1]之类的式子则用g[i]代替

  于是原式=$n * f[i] = i * f[i] + (n - i) * f[i+1] + n$

  ---> $n * f[i] - i * f[i-1] = (n - i) * f[i+1] + n$

  ---> $(n - i) * f[i] + i * f[i] - i * f[i-1] = (n - i) * f[i+1] + n$

-   --> $(n - i) * f[i] + i * (f[i] - f[i-1]) = (n - i) * f[i+1] + n$

  ---> $(n - i) * f[i] + i * g[i] = (n - i) * f[i+1] + n$

  ---> $i * g[i] = (n - i) * f[i+1] - (n - i) * f[i] + n$

  ---> $i * g[i] = (n - i) * g[i+1] + n$

  ---> $g[i]=  \frac{(n - i) * g[i+1] + n} {i}$

方法二:(某大佬的推倒)

  令$f[i]=\sum_{j = 1}^{i}{g[j]}$

  于是原式:

  $\sum_{j = 1}^{i}{g[j]} = \frac{i}{n} * \sum_{j = 1}^{i - 1}{g[j]} +\frac{n - i}{n} * \sum_{j = 1}^{i + 1}{g[j]} + 1$

  ---> 因为$\sum_{j = 1}^{i - 1}{g[j]}$ 与$ \sum_{j = 1}^{i + 1}{g[j]}$的前i-1项相同,且系数相加刚好为1,

  于是将其提出,得到:$\sum_{j = 1}^{i}{g[j]} = \sum_{j = 1}^{i - 1}{g[j]} + \frac{n - 1}{n} * (g[i] + g[i + 1]) + 1$

  $g[i] = \frac{n - i}{n} * (g[i] + g[i + 1]) + 1$ 

  然后将g[i]移项并化简得到

  $g[i] = \frac{(n - i) * g[i - 1] + n}{i}$

 
 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 100100
#define mod 100003
#define LL long long
int n,k;
LL ans,t;
LL g[AC],inv[AC];
vector<int> limit[AC];
bool z[AC];
//bitset<AC> z; inline int read()
{
int x=;char c=getchar();
while(c > '' || c < '') c=getchar();
while(c >= '' && c <= '') x=x*+c-'',c=getchar();
return x;
} void pre()
{
n=read(),k=read();
for(R i=;i<=n;i++) z[i]=read();
inv[]=;
for(R i=;i<=n;i++) inv[i]=((mod - mod / i) * inv[mod % i]) % mod;
} void count()//计算出要求的状态是什么
{
for(int i=;i<=n;i++)
for(R j=i;j<=n;j+=i)//很妙的枚举约数方法,其思想是枚举每一个约数对哪些数造成了贡献(成为它的约数)
limit[j].push_back(i);
for(R i=n;i>=;i--)
if(z[i])
{
for(R j=;j<limit[i].size();j++) z[limit[i][j]]^=;
t++;
}
// printf("%d\n",t);
}
//当状态为f[n]时,无论怎么操作都是对的,于是一定会指向f[n-1],
//所以g[n]=1,大概意思是从f[n]的状态推出题目所给的f[t]的状态的答案 void work()
{
if(t <= k) ans=t;
else
{
g[n]=;
int be=n-;
for(R i=be;i > k;i--) g[i]=( ((LL)(n - i) * g[i + ] + n) * inv[i]) % mod;
for(R i=t;i>k;i--) ans=(ans + g[i]) % mod;//统计当前状态到k之间的期望
ans=(ans + k) % mod;//最后就直接加k了
}
for(R i=;i<=n;i++) ans=(ans * i) % mod;
printf("%lld\n",ans);
} int main()
{
freopen("in.in","r",stdin);
pre();
count();
work();
fclose(stdin);
return ;
}
 

[六省联考2017]分手是祝愿 期望DP的更多相关文章

  1. [BZOJ4872][六省联考2017]分手是祝愿(期望DP)

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 516  Solved: 342[Submit][Statu ...

  2. P3750 [六省联考2017]分手是祝愿 期望DP

    \(\color{#0066ff}{ 题目描述 }\) Zeit und Raum trennen dich und mich. 时空将你我分开. B 君在玩一个游戏,这个游戏由 \(n\) 个灯和 ...

  3. [六省联考2017]分手是祝愿——期望DP

    原题戳这里 首先可以确定的是最优策略一定是从大到小开始,遇到亮的就关掉,因此我们可以\(O(nlogn)\)的预处理出初始局面需要的最小操作次数\(tot\). 然后容(hen)易(nan)发现即使加 ...

  4. BZOJ 4872 luogu P3750 [六省联考2017]分手是祝愿

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description ...

  5. bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿

    http://www.lydsy.com/JudgeOnline/problem.php?id=4872 一种最优解是 从大到小灯有亮的就灭掉 最优解是唯一的,且关灯的顺序没有影响 最优解 对每个开关 ...

  6. [BZOJ4872][六省联考2017]分手是祝愿

    BZOJ Luogu sol 首先发现肯定有解,又因为每个位置至多操作一次,所以最优解一定是在\([0,n]\)之间 有一种可以在\(O(\sum_{i=1}^{n}\lfloor\frac{n}{i ...

  7. luoguP3750 [六省联考2017]分手是祝愿 概率期望DP + 贪心

    ...........真的神状态了,没办法去想的状态................... 考试的时候选择$50$分贪心+$15$分状压吧,别的点就放弃算了........ 令$f[i]$表示从最小步 ...

  8. BZOJ4872 [六省联考2017]分手是祝愿 【期望dp】

    题目 Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态,下标为 从 1 ...

  9. 洛谷P3750 [六省联考2017]分手是祝愿(期望dp)

    传送门 嗯……概率期望这东西太神了…… 先考虑一下最佳方案,肯定是从大到小亮的就灭(这个仔细想一想应该就能发现) 那么直接一遍枚举就能$O(nlogn)$把这个东西给搞出来 然后考虑期望dp,设$f[ ...

随机推荐

  1. centos7 的防火墙命令调整了

    CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙.firewall:systemctl start firewalld.service#启动firewalls ...

  2. centos配置ip地址 添加多个ip地址的方法

    操作如下,登陆SSH: vi /etc/sysconfig/network-scripts/ifcfg-eth0: 第二个IP,就是 vi /etc/sysconfig/network-scripts ...

  3. 两分钟了解Docker的优势

    本文来自网易云社区 我们主要从Docker对业务架构和生产实践的角度来分析. 随着业务规模的逐渐扩大,产品复杂度也随着增加,企业需要解决快速迭代.高可靠和高可用等问题,一个自然的选择是服务化的拆分,把 ...

  4. C#调用大漠插件,发送QQ和微信消息

    大漠插件就不过多介绍了,不知道的请查下百度.主要是讲解C#怎么调用大漠插件. 大漠插件提供了COM版本,C#直接点击引用,添加即可.然后注册下大漠插件到系统文件夹,注册代码如下: static str ...

  5. hdu1730Northcott Game(nim博弈)

    Northcott Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. python基础之全局局部变量及函数参数

    1.局部变量和全局变量 1.1局部变量 局部变量是在函数内部定义的变量,只能在定义函数的内部使用 函数执行结束后,函数内部的局部变量会被系统收回 不同函数可以定义相同名字的局部变量,但是各用个的互不影 ...

  7. Win10系统XWware虚拟机安装Linux系统(Ubuntu)最新版教程

    XWware虚拟机安装Linux系统(Ubuntu)教程 一.下载并安装VMware虚拟机 借助VMware Workstation Pro, 我们可以在同一台Windows或Linux PC上同时运 ...

  8. Python汉诺塔问题递归算法与程序

    汉诺塔问题: 问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 ...

  9. java实现网页截图

    使用工具 java+selenium+phantomjs /chromedriver /firefox 1.分别是 phantomjs插件 google截图插件 和 firefox火狐浏览器截图插件2 ...

  10. Leetcode-跳跃游戏

    跳跃游戏     给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] ...