传送门

其实没有那么复杂

发现如果先选择数字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)相关推荐

  1. 牛客练习赛31 C 无畏死灵术士莉莲娜与锁链面纱(dfs + 期望dp)

    太久没有做期望/概率dp,已锈... 大概就是说给你一个1到n的全排列,然后每次随机选择一个数字在不改变其他数字相对位置的前提下,把比他小的数字放在他前面,大的在后面.问期望几次能够使得这个序列有序. ...

  2. 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇(逻辑+博弈) B

    链接:https://ac.nowcoder.com/acm/contest/218/B 来源:牛客网 赞迪卡之声妮莎与奥札奇 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

  3. 牛客练习赛31: D. 神器大师泰兹瑞与威穆(链表)

    链接:https://ac.nowcoder.com/acm/contest/218/D 来源:牛客网 题目描述 「只要我拉动绳线,你就得随之起舞.」          --泰兹瑞 泰兹瑞来到卡拉德许 ...

  4. 牛客练习赛46 C 华华跟奕奕玩游戏 (期望,概率)(详解)

    链接:https://ac.nowcoder.com/acm/contest/894/C 来源:牛客网 华华跟奕奕玩游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K ...

  5. 牛客练习赛81 E. 小 Q 与函数求和 1( “简单莫比乌斯反演” ,欧拉函数性质)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 牛客练习赛81 E. 小 Q 与函数求和 1( "简单莫比乌斯反演" ) Prob ...

  6. 解题报告(一)C、(牛客练习赛41 F)简单数学题(数论 + FWT)(3.5)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  7. 牛客练习赛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 ...

  8. 牛客练习赛34 - C little w and Segment Coverage(思维、树状数组)

    title: 牛客练习赛34 - C little w and Segment Coverage(思维.树状数组) date: 2018-12-15 16:36:55 tags: [树状数组,思维] ...

  9. 牛客练习赛52 | C | [烹饪] (DP,裴蜀定理,gcd)

    牛客练习赛52 C 烹饪 链接:https://ac.nowcoder.com/acm/contest/1084/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 327 ...

最新文章

  1. 面试 10+公司,囊获 8 个Offer,面经全公开
  2. 系统地学学喝酒的技巧
  3. opengl 如何加阴影_动漫嘴唇厚涂如何绘制?厚涂嘴唇正确画法
  4. python做一个linux网卡,Linux系统Python可以选择不同网卡进行网络访问吗?
  5. 普华基础软件笔试_【2019更新版】中国人民大学计算机软件考研信息汇总
  6. 防止跨站请求伪造(CSRF)攻击 和 防重复提交 的方法的实现
  7. matlab2c使用c++实现matlab函数系列教程-zeros函数
  8. css中的视距perspective和视差效果
  9. 数学建模之数据包络分析(评价投入产出比的模型)
  10. 大数据培训(第一季) java基础-徐培成-专题视频课程
  11. YGEV型系列电磁式明渠流速仪
  12. 关于专业技术资格、专业技术职务、职称三者的关系
  13. 关于日期插件在chrome中出现被遮挡的问题
  14. C语言学习:除去剪切板内容的换行与回车
  15. meTools - 每个人都能拥有的在线工具网站
  16. 发送飞信免费短信API
  17. http劫持是什么意思 ,HTTP网络劫持的手法和预防方法
  18. 没接显示器使用VNC远程黑屏
  19. python爬虫抓取房产_Python爬虫实战(3):安居客房产经纪人信息采集
  20. 【工作时间打王者】eBest 首届“荣耀杯”比赛开幕啦

热门文章

  1. linux+gunzip解压命令,Linux gunzip命令解析 gunzip解压文件的方法
  2. 与门的Python实现
  3. Python 元组() (元素不能修改),元组的定义,元组与列表的转换,元组的应用场景
  4. 渗透测试 对头像上传漏洞检测与修复
  5. Java毕业设计:校园二手闲置物品交易网站(java
  6. C/C++超全资料,编程发烧友不可不分享~~~~~~~~~
  7. c刊计算机领域见刊快的期刊,想集合大家的经历,列出一些见刊较快的期刊,以供参考!...
  8. 读取统计微信捐款(matlab)
  9. 指数和对数总结【图形+公式】
  10. Park和unPark方法