题目描述

现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望。
为了避免精度误差,你只需要输出答案模998244353的余数。

输入

输入只包含一个正整数n。N<=28

输出

输出只包含一个非负整数,表示答案模998244353的余数。
可以证明,答案一定为有理数,设其为a/b(a、b为互质的整数),你输出的整数为x,
则你需要保证0≤x<998244353且a与bx模998244353同余。

样例输入

2

样例输出

499122178


题解

状压dp+打表

套路:对于排列问题,从左到右处理比较困难的话,考虑从小到大把数插入来处理。

对于一个确定的 $1\sim n$ 的排列,令 $f[i]$ 表示该排列以第 $i$ 个数结尾的最长上升子序列长度。令 $mx[i]$ 表示其前缀最大值,显然 $mx[i]\le mx[i+1]\le mx[i]+1$ ,根据这个我们可以状压前缀最大值的差分数组。

考虑在 $i$ 位置和 $i+1$ 位置加入一个新的最大数:这个数结尾的最长上升子序列长度一定为 $mx[i]+1$ ,因此把该位改成1,这个数后面的第一个1受其影响差分数组-1,把它改成0。

设 $dp[i][j]$ 表示 $1\sim i$ 的排列,$mx$ 的差分数组状压后为 $j$ 的方案数。那么答案就是 $\sum 每种状态的数目\times 每种状态的最长上升子序列长度$ 。

代码中我没有状压 $mx[1]-mx[0]$ ,因为一定是 $1$ 。这样答案就是 $\sum\limits_{i=0}^{2^{n-1}-1}dp[n][i]·cnt[i]$ ,$cnt[i]$ 表示 $i$ 种 $1$ 的数目。

最后乘以阶乘的逆元即为期望。

时间复杂度 $O(n^2·2^n)$ ,过不去。怎么办?打表...

打表程序:

#include <cstdio>
#include <cstring>
#define mod 998244353
typedef long long ll;
int f[2][134217735] , cnt[134217735];
ll pow(ll x , int y)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % mod;
x = x * x % mod , y >>= 1;
}
return ans;
}
int main()
{
int n , i , j , k , d , t , pos;
ll ans = 0 , fac = 1;
scanf("%d" , &n) , n -- ;
f[0][0] = 1;
for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
{
memset(f[d] , 0 , sizeof(int) * (1 << i));
for(j = 0 ; j < (1 << (i - 1)) ; j ++ )
{
f[d][j << 1] = (f[d][j << 1] + f[d ^ 1][j]) % mod , pos = -1;
for(k = i - 1 ; ~k ; k -- )
{
t = ((j >> k) << (k + 1)) | (1 << k) | (j & ((1 << k) - 1));
if(j & (1 << k)) pos = k;
if(~pos) t ^= (1 << (pos + 1));
f[d][t] = (f[d][t] + f[d ^ 1][j]) % mod;
}
}
}
for(i = 1 ; i < (1 << n) ; i ++ ) cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 0 ; i < (1 << n) ; i ++ ) ans = (ans + 1ll * f[n & 1][i] * (cnt[i] + 1)) % mod;
for(i = 1 ; i <= n + 1 ; i ++ ) fac = fac * i % mod;
printf("%lld\n" , ans * pow(fac , mod - 2) % mod);
return 0;
}

AC程序:

#include <cstdio>
int a[]={1,499122178,2,915057326,540715694,946945688,422867403,451091574,317868537,200489273, 976705134,705376344,662845575,331522185,228644314,262819964,686801362,495111839,947040129,414835038,696340671,749077581,301075008,314644758,102117126,819818153,273498600,267588741},n;
int main()
{
scanf("%d",&n);
printf("%d",a[n-1]);
return 0;
}

【bzoj5161】最长上升子序列 状压dp+打表的更多相关文章

  1. bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5161 题解 回顾一下以前用二分求 LIS 的方法:令 \(f[i]\) 表示长度为 \(i\) ...

  2. BZOJ.3591.最长上升子序列(状压DP)

    BZOJ 题意:给出\(1\sim n\)的一个排列的一个最长上升子序列,求原排列可能的种类数. \(n\leq 15\). \(n\)很小,参照HDU 4352这道题,我们直接把求\(LIS\)时的 ...

  3. BZOJ 5161: 最长上升子序列 状压dp+查分

    好神啊 ~ 打表程序: #include <cstdio> #include <cstring> #include <algorithm> #define N 14 ...

  4. 洛谷 P4484 - [BJWC2018]最长上升子序列(状压 dp+打表)

    洛谷题面传送门 首先看到 LIS 我们可以想到它的 \(\infty\) 种求法(bushi),但是对于此题而言,既然题目出这样一个数据范围,硬要暴搜过去也不太现实,因此我们需想到用某种奇奇怪怪的方式 ...

  5. hdu 4352 "XHXJ's LIS"(数位DP+状压DP+LIS)

    传送门 参考博文: [1]:http://www.voidcn.com/article/p-ehojgauy-ot.html 题解: 将数字num字符串化: 求[L,R]区间最长上升子序列长度为 K ...

  6. hdu4352-XHXJ's LIS状压DP+数位DP

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门  原题目描述在最下面.  在区间内把整数看成一个阿拉伯数字的集合,此集合中最长严格上升子序列的长度为k的个数. 思路: ...

  7. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

  8. fzu2188 状压dp

    G - Simple String Problem Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  9. HDU 3001 状压DP

    有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路  成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到 ...

随机推荐

  1. Python练习-8

    1,复习 ascii:字母,数字,特殊字符:1个字节,8位 Unicode:16位 两个字节 升级 32 位 四个字节 utf-8:最少一个字节 8位表示. 英文字母 8位 1个字节 欧洲16位,2个 ...

  2. 【Beta阶段】第七次Scrum Meeting!

    每日任务内容: 本次会议为第七次Scrum Meeting会议~ 由于本次会议项目经理召开时间为10:00,在宿舍召开,召开时长约20分钟. 队员 昨日完成任务 明日要完成任务 刘乾 #177(未完成 ...

  3. Quartz中时间表达式的设置-----corn表达式 (转)(http://www.cnblogs.com/GarfieldTom/p/3746290.html)

    Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知) 时间格式: <!-- s m h d m w(?) y( ...

  4. opencv学习笔记(四)

    ROI---设定感兴趣的区域(region of interest) 定义: Mat imageROI; //方法一:通过Rect指定矩形区域 imageROI=image(Rect(500,250, ...

  5. Memcached分布式缓存快速入门

    一.从单机到分布式 走向分布式第一步就是解决:多台机器共享登录信息的问题. •例如:现在有三台机器组成了一个Web的应用集群,其中一台机器用户登录,然后其他另外两台机器共享登录状态? •解决1:Asp ...

  6. [wiki]陶德曼调停

    陶德曼调停[编辑] 维基百科,自由的百科全书 凯申物流差点和谈 目录 1背景 2调停经过 3评价 4参见 背景[编辑] 主条目:中德合作 (1911年-1941年) 1936年11月25日,德国与日本 ...

  7. ubuntu ftp服务

    apt-get install vsftpd apt-get update vi /etc/apt/sources.list vim  /etc/vsftpd.conf service vsftpd ...

  8. 第八周PSP 新折线图和饼图 个人时间管理

    1.PSP DATE START-TIME END-TIME EVENT           DELTA TYPE 4.18 15.36 16.10 读构建执法 走神5min         29mi ...

  9. 软件工程_1st weeks

    本周为软件工程课的第一周,本周主要完成了三个工作:了解了github并使用.拜读了<构建之法>并开通了博客以及完成了四则运算的代码实现. 对于第一项工作github的安装和使用,花费了5个 ...

  10. python 3以上版本使用pickle.load读取文件报UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6

    python 3以上版本使用pickle.load读取文件报UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6 ...