题解:
首先放满一行之后我们强制规定他可以继续放,这样总方案数是A(∑∣S∣,n)A(\sum |S|,n)A(∑∣S∣,n),一个方案可能被算很多次。

处理出fi,jf_{i,j}fi,j​表示前iii个第一次放满行为jjj的概率,hi,jh_{i,j}hi,j​表示前iii个种选一些数放满第jjj行的值的总和(包括第iii个),然后这道题就可以做了。

对于fff的处理只需要背包即可,对于hhh,我们发现如果枚举每个数,枚举每个位置算贡献复杂度是O(n6)O(n^6)O(n6)的,这时候注意到我们可以对一些数同时操作,具体的,记gi,j,kg_{i,j,k}gi,j,k​表示前iii个数,右边放了jjj个,长度和为kkk的没放的数的总和,si,j,ks_{i,j,k}si,j,k​表示方案数,然后处理g,sg,sg,s都是O(n5)O(n^5)O(n5)的,我们可以利用ggg数组算出前iii个种选一些数放满第jjj行的值的总和(不一定包括第iii个),然后再减一下前面的就可以得到hhh了。

#include <bits/stdc++.h>
using namespace std;const int N=55, M=3e3+50, mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (long long)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}
inline int cinv(int a) {return power(a,mod-2);}
inline void up(int &x,int y) {x=add(x,y);}struct binom {int fac[M],ifac[M];binom() {fac[0]=1;for(int i=1;i<M;i++) fac[i]=mul(fac[i-1],i);ifac[0]=ifac[1]=1;for(int i=2;i<M;i++) ifac[i]=mul(mod-mod/i,ifac[mod%i]);for(int i=2;i<M;i++) ifac[i]=mul(ifac[i-1],ifac[i]);}inline int A(int n,int m) {if(n<m) return 0;return mul(fac[n],ifac[n-m]);}inline int C(int n,int m) {if(n<m) return 0;return mul(fac[n],mul(ifac[m],ifac[n-m]));}
} C;class AnyNumber {int n,m,a[N],sum,val[N],f[M][N],g[N][N][M],s[N][N][M],h[N][N],tot;string card[N];int len[N],sl[N],pw[M];int pre[N][M],suf[N][M];inline void init_f() { // O(n^3) pre[0][0]=1;for(int i=1;i<=m;i++)for(int j=0;j<=n;j++) if(pre[i-1][j])for(int k=0;k<a[i];++k)up(pre[i][j+k],mul(pre[i-1][j],mul(C.C(j+k,j),C.A(a[i],k))));suf[m+1][0]=1;for(int i=m;i;i--)for(int j=0;j<=n;j++) if(suf[i+1][j])for(int k=0;k<a[i];++k)up(suf[i][j+k],mul(suf[i+1][j],mul(C.C(j+k,j),C.A(a[i],k))));for(int i=1;i<=m;i++)for(int j=0;j<=n;j++) if(pre[i-1][j])for(int k=0;k<=n;k++) if(suf[i+1][k])up(f[j+k+a[i]][i],mul(mul(pre[i-1][j],suf[i+1][k]),C.C(j+k,j)));}inline void init_g() { // O(n^4)s[0][0][0]=1;for(int i=1;i<=n;i++) {for(int j=0;j<i;++j)for(int l=0;l<=sl[i-1];++l) if(s[i-1][j][l]) {up(s[i][j][l],s[i-1][j][l]);up(g[i][j][l],g[i-1][j][l]);up(g[i][j][l],mul(s[i-1][j][l],val[i]));up(s[i][j+1][l+len[i]],mul(j+1,s[i-1][j][l]));up(g[i][j+1][l+len[i]],mul(j+1,g[i-1][j][l]));}}}inline void init_h() {for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) for(int k=0;k<a[j];k++)for(int l=0;l<=sl[i];++l) if(g[i][k][l]) up(h[i][j],mul(g[i][k][l],mul(C.A(i-k-1,a[j]-k-1),pw[l])));for(int i=n;i>=1;i--)for(int j=1;j<=m;j++)h[i][j]=dec(h[i][j],h[i-1][j]);}public:int findExpectation(vector<string> cards, vector<int> blank) {n=cards.size(), m=blank.size();for(int i=1;i<=n;i++) card[i]=cards[i-1];for(int i=1;i<=m;i++) a[i]=blank[i-1], sum+=a[i];for(int i=1;i<=n;i++) len[i]=card[i].size(), sl[i]=len[i]+sl[i-1];pw[0]=1; for(int i=1;i<=sl[n];i++) pw[i]=mul(pw[i-1],10);for(int i=1;i<=n;i++)for(int j=0;j<card[i].size();++j) val[i]=add(mul(val[i],10),card[i][j]-'0');init_f();init_g();init_h();int ans=0, tot=0;for(int i=1;i<=n;i++) // O(n^5)for(int j=1;j<=m;j++) if(f[i][j]) {int res=C.A(sum-i,min(n,sum)-i);int cnt=mul(f[i][j],mul(C.C(i-1,a[j]-1),C.fac[a[j]]));ans=add(ans,mul(h[i][j],mul(f[i][j],res)));tot=add(tot,mul(cnt,res));}return mul(ans,cinv(tot));}
};

Topcoder SRM 700 1000pts:AnyNumber(DP)相关推荐

  1. 300plc与组态王mpi通讯_MPI(DP)-ETH以太网转换器使用手册

    MPI(DP)-ETH 是目前最流行的西门子S7-300PLC用以太网转换器,使用方便, 对用户完全透明, 无需在上位机和PLC中添加任何程序,安装后立即可以使用.它将西门子S7-300的MPI/DP ...

  2. HDU-1284:钱币兑换问题 推理+动态规划(dp)

    文章目录 题目大意: 题目链接HDU 1284(点击可进入网页提交) 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 输入: 每行只有一个正整数N, ...

  3. 【CF 149D】Coloring Brackets(dp)

    [CF 149D]Coloring Brackets(dp) D. Coloring Brackets time limit per test 2 seconds memory limit per t ...

  4. (DP)51NOD 1183 编辑距离

    编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除 ...

  5. 设计模式:访问者(Visitor)模式

    设计模式:访问者(Visitor)模式 一.前言    什么叫做访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+ ...

  6. 求三角形最大面积(DP)

    求三角形最大面积(DP) 在OJ上奇迹般WA了:WA:70. Why? #include <iostream> #include <string.h> using namesp ...

  7. LeetCode 编辑距离 II(DP)

    1. 题目 给你两个单词 s 和 t,请你计算出将 s 转换成 t 所使用的最少操作数. 你可以对一个单词进行如下两种操作: 删除一个字符 替换一个字符 注意: 不允许插入操作 题目保证有解 示例: ...

  8. LeetCode 1220. 统计元音字母序列的数目(DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数 n,请你帮忙统计一下我们可以按下述规则形成多少个长度为 n 的字符串: - 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i ...

  9. LeetCode 265. 粉刷房子 II(DP)

    文章目录 1. 题目 2. 解题 1. 题目 假如有一排房子,共 n 个,每个房子可以被粉刷成 k 种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同. 当然,因为市场上不同颜色油 ...

最新文章

  1. 我的.net程序为何不能执行?
  2. 微软拼音输入法2007状态栏无法显示!
  3. 【转】IT名企面试:腾讯笔试题(2)
  4. 《看聊天记录都学不会C#?太菜了吧》(5)C# 中可以用中文名变量?
  5. linux中的inode节点
  6. SRM 542 DIV2
  7. 计算机网络高级技师,计算机网络管理员(高级技师)职业资格考核标准_new教案.doc...
  8. Scala中的fold和reduce理解
  9. 从测试流程角度,对产品质量的一些总结思考
  10. Linux玩dota2需要什么显卡,dota2最低配置要求 玩dota2需要什么电脑配置
  11. 交互式电子白板有哪些功能
  12. 计算机无法打印 重启又好了,打印机显示通讯错误,不能打印,但电脑重启后又好了!这是为什么?...
  13. 使用scrapy框架爬取腾讯招聘信息
  14. matlab中plot函数画线时 颜色和类型
  15. 算法 64式 4、回溯算法整理__第1部分_1到13题
  16. 耗时3个月整理的网络安全学习路线,非常详细!
  17. 【UBUNTU】ubuntu18.04安装及更新
  18. Synology群晖 DS920 +,DS420 +,DS720 +,DS220 + NAS横向对比 群晖20plus系列怎么选
  19. 集成阿里推送SDK中的问题:Duplicate zip entry UTDevice.class
  20. matlab脑电图绘画:2D头皮电位拓扑图和3D皮质层拓扑图

热门文章

  1. The Innovation | 粪菌移植治疗肥胖,如何突破瓶颈?
  2. NLP经典论文:Word2vec、CBOW、Skip-gram 笔记
  3. STM32 标准外设库(Standard Peripheral Library)
  4. 虚幻4为场景添加背景音乐的三种方法
  5. 《leetCode》:Kth Largest Element in an Array
  6. 集成学习-3.voting与bagging
  7. 2021年度总结 | 葡萄城软件开发技术回顾(下)
  8. NoSQL(MongoDB) + GraphQL 快速入门环境和资料
  9. Fass timeout detection implementation
  10. double保留两位小数的方法