计数dp做题笔记
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做题笔记的更多相关文章
- 状压dp做题笔记
CodeChef Factorial to Square (分块决策) Description 给定一个n,要求在[1,n]中删除一些数,并使剩下的数的乘积是一个完全平方数,同时要求乘积最大,求删除方 ...
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- SAM 做题笔记(各种技巧,持续更新,SA)
SAM 感性瞎扯. 这里是 SAM 做题笔记. 本来是在一篇随笔里面,然后 Latex 太多加载不过来就分成了两篇. 标 * 的是推荐一做的题目. trick 是我总结的技巧. I. P3804 [模 ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- C语言程序设计做题笔记之C语言基础知识(上)
C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...
- SDOI2017 R1做题笔记
SDOI2017 R1做题笔记 梦想还是要有的,万一哪天就做完了呢? 也就是说现在还没做完. 哈哈哈我竟然做完了-2019.3.29 20:30
- SDOI2014 R1做题笔记
SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(
- LCT做题笔记
最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...
- java做题笔记
java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...
随机推荐
- textarea文本域轻松实现高度自适应
转载:http://www.xuanfengge.com/textarea-on-how-to-achieve-a-high-degree-of-adaptive.html 今天需要些一个回复评论的页 ...
- ros 配置udev
显示已经链接设备 lsusb 显示挂载点 ls /dev/ttyACM* /dev/ttyUSB* 可以看到 ttyUSB0 和 ttyUSB1 对应哪一个设备不确定,因此,我们就需要一种方法来保证每 ...
- xss level11
Level11 (1) (2)毫无头绪,查看PHP源代码发现,是从头文件的referer获取的输入. (3)用Burp抓包,修改头文件如下: (4)再点击Proxy界面的forward,回到浏览器页面 ...
- 【Python基础】14_Python中的TODO注释
# TODO XXX... IDE中右键左下角,可显示当前项目所有的TODO
- vim 插件 入门
vim 手册 vimtutor 精简版本 help user-manual 详细手册 一些vim自带设置 set nu "显示行号 set cursorline "高亮显示当前行 ...
- Mancala II
题目描述 Mancala is a family of board games played around the world, sometimes called sowing games, or c ...
- hdu 3364 高斯入门。。
扣了一个高斯的介绍 比较全面(来自http://blog.csdn.net/duanxian0621/article/details/7408887) 高斯消元法,是线性代数中的一个算法,可用来求解线 ...
- Pattern Recognition and Machine Learning-01-Preface
Preface Pattern recognition has its origins in engineering, whereas machine learning grew out of com ...
- 解决 VS Code「Code Runner」插件运行 python 时的中文乱码问题
描述 这里整理了两种 VS Code「Code Runner」插件运行 python 时乱码的解决方案.至于设置「Auto Guess Encoding」为 true 的操作这里就不多描述了. 乱码截 ...
- JS笛卡尔积算法与多重数组笛卡尔积实现方法示例
js 笛卡尔积算法的实现代码,据对象或者数组生成笛卡尔积,并介绍了一个javascript多重数组笛卡尔积的例子,以及java实现笛卡尔积的算法与实例代码. 一.javascript笛卡尔积算法代码 ...