牛客练习赛31 C.无畏死灵术士莉莲娜与锁链面纱(期望dp)
传送门
其实没有那么复杂
发现如果先选择数字xxx,再选择数字yyy和
先选择数字yyy,再选择数字xxx没有区别,造成的影响是一样的
所以定义f[1<<20]f[1<<20]f[1<<20]为状态下的期望步数
若二进制第iii位是111说明被选择过了
那么现在就是快速求出每个状态是否合法
那么对于f[i]f[i]f[i]而言,枚举每一位二进制变成新的状态
f[i]=1+1n∗(f[a1]+f[a2]+f[a3]....+num∗f[i])f[i]=1+\frac{1}{n}*(f[a_1]+f[a_2]+f[a_3]....+num*f[i])f[i]=1+n1∗(f[a1]+f[a2]+f[a3]....+num∗f[i])
那么可以解得f[i]f[i]f[i]
如果f[i]f[i]f[i]本身本来就合法,就不需要这样转移,直接f[i]=0f[i]=0f[i]=0
合法不合法可以暴力预处理出来
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5+10;
const int mod = 998244353;
int a[22],b[22],c[22],n,ok[1<<21],f[1<<21];
void change(int index)
{int l=1,r=index+1;c[index] = index;for(int i=1;i<=n;i++)if( b[i]<index ) c[l++] = b[i];else if( b[i]>index ) c[r++] = b[i];for(int i=1;i<=n;i++) b[i] = c[i];
}
bool isok(int x)
{for(int i=1;i<=n;i++) b[i] = a[i];for(int i=0;i<n;i++){if( (x&(1<<i))==0 ) continue;change(i+1); }for(int i=1;i<=n;i++)if( b[i]!=i ) return false;return true;
}
int quick(int x,int n)
{int ans = 1;for( ; n ; n>>=1,x=x*x%mod )if( n&1 ) ans = ans*x%mod;return ans;
}
signed main()
{cin >> n;for(int i=1;i<=n;i++) cin >> a[i];int maxx = (1<<n)-1, p = quick(n,mod-2);for(int i=0;i<=maxx;i++) ok[i] = isok(i);for(int i=maxx;i>=0;i--){if( ok[i] ) continue;int num = 0;for(int j=0;j<n;j++){int nxt = i|(1<<j);if( nxt==i ) num++;else f[i] = ( f[i]+p*f[nxt]%mod )%mod;}f[i] = ( f[i]+1 )*n%mod*quick( n-num,mod-2 )%mod;}cout << f[0];
}
预处理那部分如果写成递归版本会快很多,相当于启发式合并那样不需要每次从头来过
dfs代码
官方题解另一种版本
这就更暴力了
直接把aaa序列作为状态,定义f[a]f[a]f[a]为状态为aaa时还需要的期望
所以这个fff是mapmapmap,aaa是个vectorvectorvector
那么枚举每一个数字作为本次随机选择的数字,转移是
f[a]=1+1n∗(f[a1]+f[a2]+f[a3]....+num∗f[a])f[a]=1+\frac{1}{n}*(f[a_1]+f[a_2]+f[a_3]....+num*f[a])f[a]=1+n1∗(f[a1]+f[a2]+f[a3]....+num∗f[a])
这样可以求得f[a]f[a]f[a]
记忆化搜索去解,思想差不多
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5+10;
const int mod = 998244353;
int vis[22],n,p;
map<vector<int>,int>f;
int quick(int x,int n)
{int ans = 1;for( ; n ; n>>=1,x=x*x%mod )if( n&1 ) ans = ans*x%mod;return ans;
}
int dfs(vector<int> a)
{if( f[a] ) return f[a];vector<int>b; b.resize(n);int num = 0;for(int i=0;i<n;i++){if( vis[i] ) { num++; continue; }int l=-1,r=i; b[i] = i;for(int j=0;j<n;j++)if( a[j]<i ) b[++l] = a[j];else if( a[j]>i ) b[++r] = a[j];vis[i] = 1;//已经改变过这个点了 if( a==b ) num++;else f[a] = ( f[a]+dfs(b)*p%mod )%mod;vis[i] = 0;//回溯 } return f[a] = ( 1+f[a] )*n%mod*quick( n-num,mod-2 )%mod;
}
vector<int>a;
signed main()
{cin >> n; a.resize(n);for(int i=0;i<n;i++){scanf("%lld",&a[i] );a[i]--;}p = quick(n,mod-2);cout << dfs(a);
}
牛客练习赛31 C.无畏死灵术士莉莲娜与锁链面纱(期望dp)相关推荐
- 牛客练习赛31 C 无畏死灵术士莉莲娜与锁链面纱(dfs + 期望dp)
太久没有做期望/概率dp,已锈... 大概就是说给你一个1到n的全排列,然后每次随机选择一个数字在不改变其他数字相对位置的前提下,把比他小的数字放在他前面,大的在后面.问期望几次能够使得这个序列有序. ...
- 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇(逻辑+博弈) B
链接:https://ac.nowcoder.com/acm/contest/218/B 来源:牛客网 赞迪卡之声妮莎与奥札奇 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...
- 牛客练习赛31: D. 神器大师泰兹瑞与威穆(链表)
链接:https://ac.nowcoder.com/acm/contest/218/D 来源:牛客网 题目描述 「只要我拉动绳线,你就得随之起舞.」 --泰兹瑞 泰兹瑞来到卡拉德许 ...
- 牛客练习赛46 C 华华跟奕奕玩游戏 (期望,概率)(详解)
链接:https://ac.nowcoder.com/acm/contest/894/C 来源:牛客网 华华跟奕奕玩游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K ...
- 牛客练习赛81 E. 小 Q 与函数求和 1( “简单莫比乌斯反演” ,欧拉函数性质)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 牛客练习赛81 E. 小 Q 与函数求和 1( "简单莫比乌斯反演" ) Prob ...
- 解题报告(一)C、(牛客练习赛41 F)简单数学题(数论 + FWT)(3.5)
繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...
- 牛客练习赛34 E little w and Digital Root(数位dp)
title: 牛客练习赛34 E little w and Digital Root(数位dp) date: 2018-12-17 22:38:37 tags: 数位dp categories:ACM ...
- 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)
title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...
- 牛客练习赛52 | C | [烹饪] (DP,裴蜀定理,gcd)
牛客练习赛52 C 烹饪 链接:https://ac.nowcoder.com/acm/contest/1084/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 327 ...
最新文章
- java学习规划-转的
- win10内核linux,windows 10中发布完整的Linux内核
- php随机获取文件夹,php从文件夹随机读取文件的方法
- 【2D动画】《想你》。。。。难以想象
- nao机器人行走速度_震撼!寒冬腊月里惊现多台历途外墙清洗机器人
- JavaScript (If...Else和Switch和循环遍历) 语句以及常用消息框
- Shell脚本编程之(二)简单的Shell脚本练习
- Eclipse注释快捷键、如何生成API以及可能遇到的问题解决
- oracle两天教程,Linux菜鸟的两天Oracle安装生活
- flutter 仿网易云音乐(1)
- 关于ccs软件的简单使用
- 读《因果的真相》第八、九章摘抄笔记
- aspose.words复制插入同一word文档中的某个页面
- spirng中bean对象的作用范围
- [OpenCV]关于opencv不能打开某些视频得问题
- uni-app开发的h5,使用微信授权登录(前置条件+具体代码)
- 关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
- ecg信号越界_监护仪器显示ECG是什么意思
- 年轻人不讲武德,不好好上班,用HaaS监控“老板来了”
- ug8.0更改计算机名,Ug8.0电脑名改了怎么处理
热门文章
- python基础语言与应用第五章_Python基础教程读书笔记(第5章—第6章:条件、循环和其他语句;抽象)...
- 耐克NIKE验厂的两个方面总结
- 【自动化】浅度分析自动化行业,深度好文!
- GBT 19668 (1-6)整套
- js学习笔记-2018年7月12日
- 音视频开发5. ZLMediaKit库入门使用 编译安装
- 教你python自动识别图文验证码的解决方案!
- html文件剖析 - mdn学习
- C#——设计一个简单的窗体程序,在文本框中输入两个点的坐标值,单击“确定”按钮时显示两点之间的距离。
- 如何删掉“分节符(下一页)