
翻硬币
发布日期:2021-05-07 06:54:38
浏览次数:23
分类:精选文章
本文共 2196 字,大约阅读时间需要 7 分钟。
翻 硬 币 翻硬币 翻硬币
题目链接: /
题目
小 Z Z Z离开家的时候忘记带走了钱包,掉下的硬币在桌子上排成了一列。正在等着哥哥回来的小 D D D坐在桌子旁边,无聊地翻着桌子上的硬币。
出于某种爱好,小 D D D一次一定会同时翻转 M M M枚硬币。由于小 D D D是一个爱动脑的小学生,这样进行了若干次之后她很快想到了一个问题:有多少种方法能够在 K K K次翻转后把硬币由原来的状态变成现在这样呢?
因为小 D D D是个好学的小学生,她只需要你告诉她方案数对 1000000007 1000000007 1000000007取模的值以方便她进行验算就可以了。
输入
第一行,包含三个字符 N N N, K K K, M M M ,表示硬币的数量,翻转的次数和每次翻转的硬币数量。
第 2 ~ 3 2~3 2~3 行,包含 N 个字母,表示硬币在一开始的状态和最终要变成的状态。1 表示正面而 0 表示背面。输出
一行包含一个整数,表示方案数对 1000000007 1000000007 1000000007取模的值。
样例输入
3 2 1100001
样例输出
2
样例解释
100 → 101 → 001 100→101→001 100→101→001
100 → 000 → 001 100→000→001 100→000→001数据范围
对于 30 % 30\% 30% 的数据, N ≤ 4 N ≤ 4 N≤4, 0 ≤ K ≤ 5 0 ≤ K ≤ 5 0≤K≤5;
对于 60 % 60\% 60% 的数据, N ≤ 10 N ≤ 10 N≤10; 对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100 1 ≤ N ≤ 100 1≤N≤100, 0 ≤ K ≤ 100 0 ≤ K ≤ 100 0≤K≤100, 0 ≤ M ≤ N 0 ≤ M ≤ N 0≤M≤N 。思路
这道题就是一道 d p dp dp。
设 f [ i ] [ j ] f[i][j] f[i][j]为翻 i i i次之后还有 j j j个不同的,然后我们就可以得出动态转移方程: f [ i ] [ 翻 了 之 后 不 同 的 数 量 ] = ( f [ i ] [ 翻 了 之 后 不 同 的 数 量 ] + f [ i − 1 ] [ j ] ∗ ( C [ j ] [ k k ] ∗ C [ n − j ] [ m − k k ] f[i][翻了之后不同的数量] = (f[i][翻了之后不同的数量] + f[i - 1][j] * (C[j][kk] * C[n - j][m - kk] f[i][翻了之后不同的数量]=(f[i][翻了之后不同的数量]+f[i−1][j]∗(C[j][kk]∗C[n−j][m−kk]
代码
#include#include #define ll long longusing namespace std;ll n, k, m, C[101][101], a[2][101], f[101][101], different_num, after_fan;int main() { scanf("%lld %lld %lld", &n, &k, &m);//读入 for (ll i = 1; i <= n; i++) { scanf("%1d", &a[0][i]);//读入 } getchar(); for (ll i = 1; i <= n; i++) { scanf("%1d", &a[1][i]);//读入 } for (ll i = 1; i <= n; i++) if (a[0][i] != a[1][i]) different_num++;//算出不同的硬币数 C[0][0] = 1;//初始化 for (ll i = 1; i <= n; i++) { C[i][0] = 1;//初始化 for (ll j = 1; j <= i; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % 1000000007;//递归求出组合 } f[0][different_num] = 1;//初始化 for (ll i = 1; i <= k; i++)//枚举每次翻的硬币数 for (ll j = 0; j <= n; j++)//枚举硬币数 for (ll kk = 0; kk <= min(m, j); kk++)//枚举要翻的硬币数 if (n - j >= m - kk) { //能不能翻 after_fan = j - kk + m - kk;//枚举翻了之后不同的硬币数 f[i][after_fan] = (f[i][after_fan] + f[i - 1][j] * (C[j][kk] * C[n - j][m - kk] % 1000000007) % 1000000007) % 1000000007; //dp } printf("%lld", f[k][0]);//输出 return 0;}
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年03月30日 05时02分51秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
手把手教你安装Eclipse最新版本的详细教程 (非常详细,非常实用)
2021-05-09
《带你装B,带你飞》pytest成魔之路4 - fixture 之大解剖
2021-05-09
互联网App应用程序测试流程及测试总结
2021-05-09
根据轨迹分析出用户家在哪
2021-05-09
PostgreSQL查询表名称及表结构
2021-05-09
linux中使用awk命令
2021-05-09
如何使用google搜索?
2021-05-09
Redis分布式锁的正确实现方式
2021-05-09
设计模式-抽象工厂模式
2021-05-09
IntelliJ IDEA 中,项目文件右键菜单没有svn选项解决办法
2021-05-09
IDEA 调试Java代码的两个技巧
2021-05-09
Vue 数组和对象更新,但视图未更新,背后的故事
2021-05-09
剑指Offer面试题:9.二进制中1的个数
2021-05-09
《你是在做牛做马还是在做主管》- 读书笔记
2021-05-09
重新温习软件设计之路(4)
2021-05-09
MySQL数据库与python交互
2021-05-09
python如何对字符串进行html转义与反转义?
2021-05-09
开发小白也毫无压力的hexo静态博客建站全攻略 - 躺坑后亲诉心路历程
2021-05-09