YCJS 3924 饼干

Description

给定一个长度为\(n\)的序列,序列每个元素的取值为\([1,x]\),现在给定\(q\)个区间,求在所有取值方案中,区间最小值的最大值的期望是多少?(答案对1e9+7取模)

\(n,q,x\le 2000\)

Solution

  • 首先对于这种区间问题,要找到一种转移顺序的话,就要使得这个序列有序(可以是左右端点递增)。

  • 然后对于这道题目,考虑枚举最小值的最大值\(ans\)。

  • 性质1:如果区间a包含区间b,那么\(ans\)只可能存在于区间b中。

  • 所以可以通过该性质删去一些区间,然后转移就有序了。

  • 性质2:如果区间有序,那么所有有被区间包含的点\(a_i\),包含它们的区间的编号也是递增的。

  • 那么可以比较容易定义出一个\(O(n^3)\)的转移。

  • 首先枚举ans,然后每个区间就一定要存在至少一个点的权值\(\le ans\) 然后答案为ans的方案就是\(F[ans]-F[ans-1]\)

  • 定义\(dp_{i,j}\) 为枚举到第i个点,满足到第j个区间的方案数,发现转移是\(O(1)\)的,因为只用知道当前点要填的数是否>ans就可以计算出转移到的状态。

  • 然后化简状态,令\(dp_i\) 表示第i个点的权值\(<=ans\),且填到第i个点仍是合法的方案数。

  • 定义 \(L_i\)表示覆盖第i个点的区间的最小编号,\(R_i\)表示覆盖第i个点的最大编号

  • 那么转移方程为$$dp_i=ans\sum\limits _{R_j\ge L_i-1} dp_j(x-ans)^{i-j-1}$$

  • 进一步化简$$dp_i=ans(x-ans)^i\sum \limits_{R_j\ge L_i-1} dp_j*(x-ans)^{-j-1}$$

  • 由性质2可得,满足条件的j是一端连续的区间,所以可以用前缀和维护后面一端累和,然后转移就是\(O(1)\)的了。

  • 总复杂度\(O(n^2)\)

hihocoder 1758 加减

[数位dp+概率期望]

Description

对于一个二进制位数x ,有50%的概率 -lowbit(x),有50%的概率 +lowbit(x)

令Sum[x]表示x变化为0的期望变化次数,求 \(\sum \limits _{i=l}^{r} Sum[i]\) 的值 答案对998244353取模

  • \(l\le r< 2^{31}\)

Solution

分析操作性质

对于两个等概率操作,-lowbit(x)等于减去最小的二进制位,+lowbit(x)等于从最小的二进制位开始进位

需要记录信息及转移

进行数位dp,记f[1]为后面的数进位过来的期望步数,g[1]为从后面进位过来的概率总和

如果当前点为0的话,那么在此时,当前位为lowbit,需要进行一次操作,有50%的概率进位到前面

所以当前位的 \(f_{now}[1]=\frac{1}{2}\times (g[1]+f[1])\) ,\(g_{now}[1]=\frac{1}{2}\times g[1]\),同理当前位为0的情况

Code

#include<cstdio>
#include<cstring>
#define FOR(i,x,y) for(int i=(x),i##_END=(y);i<=i##_END;++i)
#define DOR(i,x,y) for(int i=(x),i##_END=(y);i>=i##_END;--i)
const int P=998244353;
typedef long long LL;
int fast(int x,int n){int res=1;for(;n;n>>=1,x=(LL)x*x%P)if(n&1)res=(LL)res*x%P;return res;}
inline void add(int &x,int y){x+=y;if(x>=P)x-=P;}
struct node{
int f[2],g[2];
node(){f[0]=f[1]=0,g[0]=g[1]=0;}
}dp[36],T;
bool mark[36];
int limits[36],H,Inv; node dfs(int x,bool f){
if(!x)return T;
if(!f&&mark[x])return dp[x];
node D;
FOR(i,0,f?limits[x]:1){
node E=dfs(x-1,f&&i==limits[x]);
if(i==1){
add(D.f[1],E.f[1]);
add(D.g[1],E.g[1]);
add(D.f[0],(LL)E.f[0]*Inv%P);
add(D.f[0],(LL)E.g[0]*Inv%P);
add(D.g[0],(LL)E.g[0]*Inv%P);
add(D.f[1],(LL)E.f[0]*Inv%P);
add(D.f[1],(LL)E.g[0]*Inv%P);
add(D.g[1],(LL)E.g[0]*Inv%P);
}else {//i==0
add(D.f[0],E.f[0]);
add(D.g[0],E.g[0]);
add(D.f[1],(LL)E.f[1]*Inv%P);
add(D.f[1],(LL)E.g[1]*Inv%P);
add(D.g[1],(LL)E.g[1]*Inv%P);
add(D.f[0],(LL)E.f[1]*Inv%P);
add(D.f[0],(LL)E.g[1]*Inv%P);
add(D.g[0],(LL)E.g[1]*Inv%P);
}
}
if(!f){
mark[x]=true;
dp[x]=D;
}
return D;
} int Solve(int x){
if(!x)return 0;
H=0;
memset(limits,0,sizeof limits);
while(x)limits[++H]=x%2,x/=2;
node res=dfs(H,1);
return ((LL)res.f[0]+res.f[1]+res.g[1]*2)%P;
} int main(){
T.f[0]=0,T.f[1]=0;
T.g[0]=1,T.g[1]=0; int L,R;
Inv=fast(2,P-2);
scanf("%d%d",&L,&R);
printf("%d\n",(Solve(R)-Solve(L-1)+P)%P);
return 0;
}

计数dp做题笔记的更多相关文章

  1. 状压dp做题笔记

    CodeChef Factorial to Square (分块决策) Description 给定一个n,要求在[1,n]中删除一些数,并使剩下的数的乘积是一个完全平方数,同时要求乘积最大,求删除方 ...

  2. SDOI2016 R1做题笔记

    SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...

  3. SAM 做题笔记(各种技巧,持续更新,SA)

    SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...

  4. C语言程序设计做题笔记之C语言基础知识(下)

    C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

  5. C语言程序设计做题笔记之C语言基础知识(上)

    C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...

  6. SDOI2017 R1做题笔记

    SDOI2017 R1做题笔记 梦想还是要有的,万一哪天就做完了呢? 也就是说现在还没做完. 哈哈哈我竟然做完了-2019.3.29 20:30

  7. SDOI2014 R1做题笔记

    SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(

  8. LCT做题笔记

    最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...

  9. java做题笔记

    java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...

随机推荐

  1. textarea文本域轻松实现高度自适应

    转载:http://www.xuanfengge.com/textarea-on-how-to-achieve-a-high-degree-of-adaptive.html 今天需要些一个回复评论的页 ...

  2. ros 配置udev

    显示已经链接设备 lsusb 显示挂载点 ls /dev/ttyACM* /dev/ttyUSB* 可以看到 ttyUSB0 和 ttyUSB1 对应哪一个设备不确定,因此,我们就需要一种方法来保证每 ...

  3. xss level11

    Level11 (1) (2)毫无头绪,查看PHP源代码发现,是从头文件的referer获取的输入. (3)用Burp抓包,修改头文件如下: (4)再点击Proxy界面的forward,回到浏览器页面 ...

  4. 【Python基础】14_Python中的TODO注释

    # TODO XXX... IDE中右键左下角,可显示当前项目所有的TODO

  5. vim 插件 入门

    vim 手册 vimtutor 精简版本 help user-manual 详细手册 一些vim自带设置 set nu "显示行号 set cursorline "高亮显示当前行 ...

  6. Mancala II

    题目描述 Mancala is a family of board games played around the world, sometimes called sowing games, or c ...

  7. hdu 3364 高斯入门。。

    扣了一个高斯的介绍 比较全面(来自http://blog.csdn.net/duanxian0621/article/details/7408887) 高斯消元法,是线性代数中的一个算法,可用来求解线 ...

  8. Pattern Recognition and Machine Learning-01-Preface

    Preface Pattern recognition has its origins in engineering, whereas machine learning grew out of com ...

  9. 解决 VS Code「Code Runner」插件运行 python 时的中文乱码问题

    描述 这里整理了两种 VS Code「Code Runner」插件运行 python 时乱码的解决方案.至于设置「Auto Guess Encoding」为 true 的操作这里就不多描述了. 乱码截 ...

  10. JS笛卡尔积算法与多重数组笛卡尔积实现方法示例

    js 笛卡尔积算法的实现代码,据对象或者数组生成笛卡尔积,并介绍了一个javascript多重数组笛卡尔积的例子,以及java实现笛卡尔积的算法与实例代码. 一.javascript笛卡尔积算法代码 ...