期望dp好题选做
前言:
最近连考两场期望dp的题目,sir说十分板子的题目我竟然一点也不会,而且讲过以后也觉得很不可改。于是开个坑。
1.晚测10 T2 大佬(kat)
明明有\(O(mlog)\)的写法,但是\(m\)等于\(500\)就让人十分迷惑。当然我并没有推出来
以下式子来自这里
emm,目前觉得DeepinC的式子最好理解,也最好写 其实我就看懂了一个
下面的\(m^k\)显然是总方案数,后面乘的\((n-k+1)\)提醒我们这个式子是在枚举每一个区间。
至于分子上的东西,
从\(1\)到\(m\)枚举当前区间造成贡献的数是多少。
假设当前枚举到\(i\)
那么方案数就是\(i^k-(i-1)^k\) ,前面是每个数值域在\([1,i]\)的方案数,后面是每个数值域在\([1,i-1]\)的方案数,相减就是这个区间内至少有一个是\(i\)的方案数。
然后乘以对应的\(w[i]\),求个和。
实际意义大概就是这样的。
P.S.
那我为什么交了折磨多次68分呢?
不会真的有人能看到m是500吧,不会吧不会吧不会吧
1.联考Day5 T2 客星璀璨之夜
貌似是HDU 6848的弱化版?
这个题可以\(O(n^2)\)解决掉。原题貌似就要\(O(nlog)\)了,我不会。
首先,这类题目的一个常用套路是,用每一个元素对答案的贡献,乘以每一个元素的贡献次数,求和再除以总方案数。
这个题里面,首先可以发现,每条路径出现的次数只与当前的点数和这条路径第一个点的位置有关。
所以我们用dp[i][j]表示,这条路径中间有i对点,右面有j对点的方案数(不考虑左面的方案数,当作左面是0个)。
考虑转移。
dp[i][j]=dp[i-1][j]*(i*2-1)+dp[i][j-1]*(j*2+1);
这里我们相当与枚举下一次是哪个点进行碰撞。中间有i对点,除了最右面的,其他点都可以向左或向右。右面的j对点同理。
当然,有:
\(dp[0][0]=1\)
\(dp[0][i]=dp[0][i-1]*(i*2-1)*i!*2^i\)
\(dp[i][0]=dp[i-1][0]*(i*2-1)\)
这里要说一下\(dp[0][i]\)和\(dp[i][0]\)转移的区别。
\(dp[i][0]\):右面没有点对。也就是说,我们选择作出贡献的点对必须在i对点碰撞完之后才能进行碰撞。
\(dp[0][i]\):中间没有点对,也就是说,我们选择作出贡献的点对可以在i对点碰撞的过程中进行碰撞,所以要乘以\((i!*2^i)\)
然后我们就求出了方案数(左面的方案没有乘)
现在只要枚举造成贡献的路径,再乘以对应的dp[i][j],再乘以左面的方案数,再求个和,最后除以总方案数,就完了!
具体实现:第一维枚举奇数点,第二维枚举偶数点。如果x<y,就普通算,如果是x>y,就让x=2n+1-x+1,y=2n+1-y,相当与让整个序列反转,这样求方案数更加方便。
当然,如果这么敲上去,大概会拿到90分的好成绩,因为快速幂带个log,就很烦。
只要预处理一下就行了。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3000+10,maxm=6000+10,mod=998244353;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
int a[maxm];
ll dp[maxn][maxn];
ll fac[maxn],facn[maxn],n2[maxn];
int n;
ll ans;
ll qpow(ll x,int y){
ll res=1;
ll base=x;
while(y){
if(y&1) res=res*base%mod;
base=base*base%mod;
y>>=1;
}
return res;
}
void Solve(){
scanf("%d",&n);
fac[0]=1;
for(register int i=1;i<=n;++i) fac[i]=fac[i-1]*i%mod;
for(int i=1;i<=n;++i) facn[i]=qpow(fac[i],mod-2);
n2[0]=1;
for(int i=1;i<=n;++i) n2[i]=qpow(2,i);
for(register int i=1;i<=(n<<1)+1;++i) scanf("%d",&a[i]);
dp[0][0]=1;
for(register int i=1;i<=n;++i){
dp[i][0]=dp[i-1][0]*(i*2-1)%mod;
dp[0][i]=(dp[0][i-1]*(i*2-1)%mod+fac[i]%mod*qpow(2,i)%mod)%mod;
}
for(register int i=1;i<=n;++i){
for(register int j=1;j<=n;++j){
dp[i][j]=(dp[i-1][j]*(i*2-1)+dp[i][j-1]*(j*2-1))%mod;
}
}
for(register int i=2;i<=(n*2);i+=2){
for(register int j=1;j<=n*2+1;j+=2){
int x=i;
int y=j;
if(x>y) x=2*n+1-x+1,y=2*n+1-y;
ans=(ans+1ll*abs(a[i]-a[j])*dp[(y-x)/2][(n*2+1-y)/2]%mod*n2[(x-2)/2]%mod*fac[n]%mod*facn[n-(x-2)/2])%mod;
//ans=(ans+1ll*abs(a[i]-a[j])*dp[(y-x)/2][(n*2+1-y)/2]%mod*qpow(2,(x-2)/2)%mod*fac[n]%mod*qpow((fac[n-(x-2)/2]),mod-2))%mod;
}
}
ans=ans*qpow(qpow(2,n)*fac[n]%mod,mod-2)%mod;
printf("%lld\n",ans);
}
int main(){
//freopen("stars.in","r",stdin);
//freopen("stars.out","w",stdout);
Solve();
return 0;
}
期望dp好题选做的更多相关文章
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- 贪心/构造/DP 杂题选做Ⅱ
由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...
- 贪心/构造/DP 杂题选做
本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...
- Atcoder 水题选做
为什么是水题选做呢?因为我只会水题啊 ( 为什么是$Atcoder$呢?因为暑假学长来讲课的时候讲了三件事:不要用洛谷,不要用dev-c++,不要用单步调试.$bzoj$太难了,$Topcoder$整 ...
- [SDOI2016]部分题选做
听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...
- HDU3853 LOOPS 期望DP基础题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3853 题目大意(只是大意,名字什么的可能和原题描述不一样~): 爱丽丝与华容道 题目描述 爱丽丝是一个 ...
- 花园【SCOI2017期望DP入门题】
题目描述: 小 A 的花园的长和宽分别是 L,H .小 A 喜欢在花园里做游戏.每次做游戏的时候,他都先把花园均匀分割成 L×H 个小方块,每个方块的长和宽都是 1 .然后,小 A 会从花园的西北角的 ...
- 【SPOJ GSS】数据结构题选做
SPOJ GSS1 题意:给一个序列以及一些询问,每个是问\([l,r]\)中最大连续子序列和是多少. 思路:这个问题是以下问题的基础. 我们考虑用线段树来解决这个问题. 首先我们来想想如果要求出最大 ...
- [NOIP2017(TG/PJ)] 真题选做
[NOIPTG2017] 小凯的疑惑 题意 小凯有两种面值的金币,每种金币有无数个,求在无法准确支付的物品中,最贵的价值是多少金币. 分析 设两种金币面值分别为 $a$ 和 $b \; (a<b ...
随机推荐
- request内部转发Demo
// 转发的Demo1 import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import ja ...
- redis的集群安装
1.创建安装目录 在master ,node1 ,node2中分别创建 mkdir /usr/local/soft/redis-cluster 2.将redis 复制到redis-cluster 目录 ...
- CodeForce-807C Success Rate(二分数学)
Success Rate CodeForces - 807C 给你4个数字 x y p q ,要求让你求最小的非负整数b,使得 (x+a)/(y+b)==p/q,同时a为一个整数且0<=a< ...
- scrum项目冲刺_day08总结
摘要:今日完成任务. 1.短信服务正在进行 2.注册登录功能基本实现,但缺少短信验证 3.导航在进行 4.搜索功能基本完成 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已 ...
- PC端利用Xshell连接Android上的Termux
需要准备的工具 Android端:Termux.RE管理器 PC端:Xshell 开始操作 1. 启动Termux,安装openssh pkg install openssh 2. 安装好后,启动ss ...
- 判断手机浏览器还是微信浏览器(PHP)
//判断是否 微信浏览器 function isWeixin1() { if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== fa ...
- MySQL update 链表 (一个表数据当做条件错误时候的转换)
MySQL语句一: UPDATE lesson_p set solve_status = 6 where lesson_p_id in (SELECT lp.lesson_p_id FROM `les ...
- python学习笔记(二)-字符串方法
python的字符串内建函数: #====================常用方法=============================name = 'besttest' new_name = n ...
- adb devices如何连逍遥模拟器的设备
adb device连接真机,上一篇已经讲过了,这篇讲如何连接模拟器.这里我用的模拟器逍遥模拟器.我先插上手机,另外启动了一个模拟器,直接在cmd中输入adb devices,按理应该有2个设备id, ...
- 『Python』matplotlib实现GUI效果
1. 类RadioButtons的使用方法 类似单选框 import numpy as np import matplotlib.pyplot as plt import matplotlib as ...