翻硬币
发布日期: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 23 行,包含 N 个字母,表示硬币在一开始的状态和最终要变成的状态。1 表示正面而 0 表示背面。

输出

一行包含一个整数,表示方案数对 1000000007 1000000007 1000000007取模的值。

样例输入

3 2 1100001

样例输出

2

样例解释

100 → 101 → 001 100→101→001 100101001

100 → 000 → 001 100→000→001 100000001

数据范围

对于 30 % 30\% 30% 的数据, N ≤ 4 N ≤ 4 N4 0 ≤ K ≤ 5 0 ≤ K ≤ 5 0K5

对于 60 % 60\% 60% 的数据, N ≤ 10 N ≤ 10 N10
对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100 1 ≤ N ≤ 100 1N100 0 ≤ K ≤ 100 0 ≤ K ≤ 100 0K100 0 ≤ M ≤ N 0 ≤ M ≤ N 0MN

思路

这道题就是一道 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[i1][j](C[j][kk]C[nj][mkk]
在这里插入图片描述

代码

#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;}
上一篇:MySql索引及使用、实现的数据结构
下一篇:SpringBoot整合JDBC、Mybatis、SpringData JPA

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年03月30日 05时02分51秒