文章目录

  • T1:chocolate
    • 题目
    • 题解
    • code
  • T2:“红色病毒”问题
    • 题目
    • 题解
    • code
  • T3:排列组合
    • 题目
    • 题解
    • code
  • T4:字串数
    • 题解
    • code

T1:chocolate

题目

已帮大家翻译了,不要去UVA或者luogu上面交,卡精度,

在2100年,ACM巧克力将成为世界上最受欢迎的食品之一。

“绿色,橙色,棕色,红色…”,彩色糖衣壳也许是ACM巧克力最吸引人的特征。您见过多少种颜色?如今,据说ACM从二十四种颜色的调色板中进行选择来绘制其美味的糖果。

一天,桑迪在一大包ACM巧克力上玩游戏,其中包含五种颜色(绿色,橙色,棕色,红色和黄色)。每次他从包装中取出一个巧克力并将其放在桌子上。如果桌子上有两个颜色相同的巧克力,他会把它们都吃掉。他发现一件很有趣的事情,在大多数情况下,桌上总是有2或3块巧克力。

现在,问题来了,如果包装中有C种颜色的ACM巧克力(颜色均匀分布),那么从包装中取出N颗巧克力后,桌上有M颗巧克力的概率是多少?您可以编写一个程序来解决吗?

输入
此问题的输入文件包含几个测试用例,每行一个
对于每种情况,都有三个非负整数:C(C <= 100),N和M(N,M <= 1000000)
输入由包含单个零的行终止。
输出
输出应该是每行一个实数,显示每种情况的概率,四舍五入到小数点后三位

样本输入
5 100 2

0
样本输出
0.625

题解

首先我们由题意知道如果桌子上有两个颜色相同的巧克力,会被吃掉,所以最后桌子上的巧克力一定是互不相同的,也就是有mmm种不同的糖果留在上面,所以我们可以特判当m>cm>cm>c时,是无解的


当m>nm>nm>n时,脑子也想得出来是无解的,一共就nnn颗,你从哪里变出m−nm-nm−n颗


再来每次都是两颗两颗地吃,所以n−mn-mn−m也就是吃的颗数一定是偶数,所以也可以特判一下


接下来进入母函数板块
首先是
前面提到过最后剩在桌上的糖果一定都是互不相同的,剩mmm颗,也就是剩mmm种,那么这mmm种糖果拿的数量一定是奇数(最后剩下一个不能吃),剩下的c−mc-mc−m种糖果拿的一定是偶数(都被两两吃掉),如果你不能理解就算了 ,且吃的顺序不同算不同的方法加上是等概率,那么总情况就是cnc^ncn
我们考虑最普通的指数型函数
1+x1!+x22!+...+xnn!+...=ex1+\frac{x}{1!}+\frac{x^2}{2!}+...+\frac{x^n}{n!}+...=e^x1+1!x​+2!x2​+...+n!xn​+...=ex
奇数的糖果的话就要想办法消掉x偶数项x^{偶数项}x偶数项,偶数的糖果就要想办法消掉x奇数项x^{奇数项}x奇数项
奇数项:ex−e−x2\frac{e^x-e^{-x}}{2}2ex−e−x​
偶数项:ex+e−x2\frac{e^x+e^{-x}}{2}2ex+e−x​

不要慌,我们来带一下e−x=1+−x1!+(−x)22!+...+(−x)nn!e^{-x}=1+\frac{-x}{1!}+\frac{(-x)^2}{2!}+...+\frac{(-x)^n}{n!}e−x=1+1!−x​+2!(−x)2​+...+n!(−x)n​
以奇数项为例,偶数项相信大家看完后会秒懂
ex−e−x2=(1−1)+(x−(−x))+(x2−(−x)2)+...+(xn−(−x)n)+...2\frac{e^x-e^{-x}}{2}=\frac{(1-1)+(x-(-x))+(x^2-(-x)^2)+...+(x^n-(-x)^n)+...}{2}2ex−e−x​=2(1−1)+(x−(−x))+(x2−(−x)2)+...+(xn−(−x)n)+...​=2x+2x3+2x5+...2=x+x3+x5+...=\frac{2x+2x^3+2x^5+...}{2}=x+x^3+x^5+...=22x+2x3+2x5+...​=x+x3+x5+...

那么把每一种糖果对应的母函数乘起来,即
(ex−e−x2)m+(ex−e−x2)c−m(\frac{e^x-e^{-x}}{2})^m+(\frac{e^x-e^{-x}}{2})^{c-m}(2ex−e−x​)m+(2ex−e−x​)c−m
运用二项式展开定理得到,看来我还得去学学这玩意儿
∑i=0m(−1)i∗Cmi∗e(m−i)∗x∗e−ix2m×∑i=0c−mCc−mi∗e(c−m−i)x∗e−ix2c−m\frac{\sum_{i=0}^m\ (-1)^i*C_m^i*e^{(m-i)*x}*e^{-ix}}{2^m}×\frac{\sum_{i=0}^{c-m}C_{c-m}^i*e^{(c-m-i)x}*e^{-ix}}{2^{c-m}}2m∑i=0m​ (−1)i∗Cmi​∗e(m−i)∗x∗e−ix​×2c−m∑i=0c−m​Cc−mi​∗e(c−m−i)x∗e−ix​
∑i=0m(−1)i∗Cmi∗e(m−2i)x×∑i=0c−mCc−mi∗e(c−m−2i)x2c\frac{\sum_{i=0}^m(-1)^i*C_m^i*e^{(m-2i)x}×\sum_{i=0}^{c-m}C_{c-m}^i*e^{(c-m-2i)x}}{2^c}2c∑i=0m​(−1)i∗Cmi​∗e(m−2i)x×∑i=0c−m​Cc−mi​∗e(c−m−2i)x​
我们先把分母放一放,先只看分子,对其进行化简
∑i=0m∑j=0c−m(−1)i∗Cmi∗Cc−mj∗e(c−2i−2j)x\sum_{i=0}^m\sum_{j=0}^{c-m}(-1)^i*C_m^i*C_{c-m}^j*e^{(c-2i-2j)x}i=0∑m​j=0∑c−m​(−1)i∗Cmi​∗Cc−mj​∗e(c−2i−2j)x
将这个的封闭式展开,变成
∑k=0∞∑i≤0≤m,j≤0≤c−m(−1)i∗Cmi∗Cc−mj∗(c−2i−2j)kk!∗xk\sum_{k=0}^∞\frac{\sum_{i\le0\le m,j\le0\le c-m}(-1)^i*C_m^i*C_{c-m}^j*{(c-2i-2j)^k}}{k!}*x^kk=0∑∞​k!∑i≤0≤m,j≤0≤c−m​(−1)i∗Cmi​∗Cc−mj​∗(c−2i−2j)k​∗xk
但是这里我们不能忘记上面的分母和总情况2c,cn2^c,c^n2c,cn,最后剩下的是哪mmm种,还有一个CcmC_c^mCcm​
所以最后第nnn项的系数就是Ccm2c∗cn∗∑i≤0≤m,j≤0≤c−m(−1)i∗Cmi∗Cc−mj∗(c−2i−2j)k\frac{C_c^m}{2^c*c^n}*\sum_{i\le0\le m,j\le0\le c-m}(-1)^i*C_m^i*C_{c-m}^j*{(c-2i-2j)^k}2c∗cnCcm​​∗i≤0≤m,j≤0≤c−m∑​(−1)i∗Cmi​∗Cc−mj​∗(c−2i−2j)k

code

本来刚开始快速幂和组合数都不想开doubledoubledouble,但是同胞告诉我会炸intintint

#include <cstdio>
#include<iostream>
using namespace std;
#define MAXN 200
#define _for(i,a,b) for(int i=(a);i<=(b);++i)
double C[MAXN + 5][MAXN + 5];double qkpow ( double x, int y ) {double ans = 1;while ( y ) {if ( y & 1 )ans = ans * x;x *= x;y >>= 1;}return ans;
}void init () {C[0][0] = 1;for ( int i = 1;i <= MAXN;i ++ ) {C[i][0] = 1;for ( int j = 1;j <= i;j ++ )C[i][j] = C[i - 1][j - 1] + C[i - 1][j];}
}int main() {int n, c, m;init();while ( scanf ( "%d", &c ) && c != 0 ) {scanf ( "%d %d", &n, &m );if ( m > c || m > n || ( n - m ) & 1 ) {printf ( "0.000\n" );continue;}double result = 0;for ( int i = 0;i <= m;i ++ )for ( int j = 0;j <= c - m;j ++ )result += ( i & 1 ? -1 : 1 ) * C[m][i] * C[c - m][j] * qkpow ( c - ( i << 1 ) - ( j << 1 ), n );result *= C[c][m] / qkpow ( 2, c ) / qkpow ( c, n );printf ( "%.3f\n", result );}return 0;
}

T2:“红色病毒”问题

题目

医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.

Input
每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<2^64),当T=0时结束.
Output
对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.

Sample Input
4
1
4
20
11
3
14
24
6
0
Sample Output
Case 1: 2
Case 2: 72
Case 3: 32
Case 4: 0

Case 1: 56
Case 2: 72
Case 3: 56

题解

对于B,DB,DB,D是没有限制的,那么它们的生成函数则是普通型
1+x1!+x22!+x33!......=ex1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}......=e^x1+1!x​+2!x2​+3!x3​......=ex
而A,CA,CA,C的要求是必须出现偶数次,当然不出现也行,所以他们的生成函数就只能保留x偶数次x^{偶数次}x偶数次
1+x22!+x44!+......=ex+e−x21+\frac{x^2}{2!}+\frac{x^4}{4!}+......=\frac{e^x+e^{-x}}{2}1+2!x2​+4!x4​+......=2ex+e−x​
所以先写T1的题解不是没有逻辑的
将四个的生成函数闭形式相乘来化简试试
(ex)2∗(ex+e−x2)2=e2x∗e2x+e−2x+24=e4x+2e2x+14(e^x)^2*(\frac{e^x+e^{-x}}{2})^2=e^{2x}*\frac{e^{2x}+e^{-2x}+2}{4}=\frac{e^{4x}+2e^{2x}+1}{4}(ex)2∗(2ex+e−x​)2=e2x∗4e2x+e−2x+2​=4e4x+2e2x+1​
然后还原成母函数
e4x=1+4x1!+(4x)22!+...(4x)nn!+....e^{4x}=1+\frac{4x}{1!}+\frac{(4x)^2}{2!}+...\frac{(4x)^n}{n!}+....e4x=1+1!4x​+2!(4x)2​+...n!(4x)n​+....
2e2x=2(1+2x1!+(2x)22!+...+(2x)nn!+...)=2+4x1!+8x2!+...+2(2x)nn!+...2e^{2x}=2(1+\frac{2x}{1!}+\frac{(2x)^2}{2!}+...+\frac{(2x)^n}{n!}+...)=2+\frac{4x}{1!}+\frac{8x}{2!}+...+\frac{2(2x)^n}{n!}+...2e2x=2(1+1!2x​+2!(2x)2​+...+n!(2x)n​+...)=2+1!4x​+2!8x​+...+n!2(2x)n​+...
所以
e4x+2e2x+14=14∗(4+4x+2∗2x1!+(4x)2+2∗(2x)22!+...+(4x)n+2(2n)nn!)+...\frac{e^{4x}+2e^{2x}+1}{4}=\frac{1}{4}*(4+\frac{4x+2*2x}{1!}+\frac{(4x)^2+2*(2x)^2}{2!}+...+\frac{(4x)^n+2(2n)^n}{n!})+...4e4x+2e2x+1​=41​∗(4+1!4x+2∗2x​+2!(4x)2+2∗(2x)2​+...+n!(4x)n+2(2n)n​)+...
=14∗(4+(4+2∗2)x1!+(42+2∗22)x22!+...(4n+2∗2n)xnn!+...)=\frac{1}{4}*(4+(4+2*2)\frac{x}{1!}+(4^2+2*2^2)\frac{x^2}{2!}+...(4^n+2*2^n)\frac{x^n}{n!}+...)=41​∗(4+(4+2∗2)1!x​+(42+2∗22)2!x2​+...(4n+2∗2n)n!xn​+...)
常数项是第零项,把14\frac{1}{4}41​乘进去,所以第nnn项的系数应该是
14∗(4n+2∗2n)=4n−1+2n−1\frac{1}{4}*(4^{n}+2*2^{n})=4^{n-1}+2^{n-1}41​∗(4n+2∗2n)=4n−1+2n−1

code

#include <cstdio>
#include <iostream>
using namespace std;
#define mod 100
#define LL unsigned long long
LL n;LL qkpow ( LL x, LL y ) {LL ans = 1;while ( y ) {if ( y & 1 )ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}int main() {int T; while ( scanf ( "%d", &T ) && T != 0 ) {int Case = 0;while ( T -- ) {cin >> n;printf ( "Case %d: %lld\n", ++ Case, ( qkpow ( 2, n - 1 ) + qkpow ( 4, n - 1 ) ) % mod );  }printf ( "\n" ); }return 0;
}

T3:排列组合

题目

有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。
Input
每组输入数据有两行,第一行是二个数n,m(1<=m,n<=10),表示物品数,第二行有n个数,分别表示这n件物品的数量。
Output
对应每组数据输出排列数。(任何运算不会超出2^31的范围)
Sample Input
2 2
1 1
Sample Output
2

题解

我们对于每一种物品数,都可以写出其生成函数
i∈[1,n],1+x1!+x22!+x33!+...+xnum[i]num[i]!i∈[1,n],1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+...+\frac{x^{num[i]}}{num[i]!}i∈[1,n],1+1!x​+2!x2​+3!x3​+...+num[i]!xnum[i]​
设dp[j]dp[j]dp[j]表示选了jjj个物品的排列数,那么对于第iii种物品而言,我们枚举该种物品选的个数是k∈[1,num[i]]k∈[1,num[i]]k∈[1,num[i]],那么排列数就要加上kkk个物品的排列数,但是因为它们是一种,顺序没有用,所以要除掉k!k!k!
于是可以写出转移方程式dp[j+k]=dp[j+k]+dp′[j]/k!dp[j+k]=dp[j+k]+dp'[j]/k!dp[j+k]=dp[j+k]+dp′[j]/k!

code

这就像是一种模板了。。

#include <cstdio>
#include <cstring>
#define MAXN 15
int n, m;
int fac[MAXN], num[MAXN];
double dp1[MAXN], dp2[MAXN];void init () {fac[0] = fac[1] = 1;for ( int i = 2;i < MAXN;i ++ )fac[i] = i * fac[i - 1];
}int main() {init();while ( ~ scanf ( "%d %d", &n, &m ) ) {for ( int i = 1;i <= n;i ++ )scanf ( "%d", &num[i] );memset ( dp1, 0, sizeof ( dp1 ) );memset ( dp2, 0, sizeof ( dp2 ) );for ( int i = 0;i <= num[1];i ++ )dp2[i] = 1.0 / fac[i];for ( int i = 2;i <= n;i ++ ) {for ( int j = 0;j <= m;j ++ )for ( int k = 0;k <= num[i];k ++ )if ( j + k > m )break;elsedp1[j + k] += dp2[j] / fac[k];for ( int j = 0;j <= m;j ++ ) {dp2[j] = dp1[j];dp1[j] = 0;}}printf ( "%.0lf\n", dp2[m] * fac[m] );}return 0;
}

T4:字串数

一个A和两个B一共可以组成三种字符串:“ABB”,“BAB”,“BBA”.
给定若干字母和它们相应的个数,计算一共可以组成多少个不同的字符串.
Input
每组测试数据分两行,第一行为n(1<=n<=26),表示不同字母的个数,第二行为n个数A1,A2,…,An(1<=Ai<=12),表示每种字母的个数.测试数据以n=0为结束.
Output
对于每一组测试数据,输出一个m,表示一共有多少种字符串.
Sample Input
2
1 2
3
2 2 2
0
Sample Output
3
90

题解

这道题跟上面第三题有点相似,我们可以先看对于nnn个字符,一共可以拼凑出n!n!n!个字符串
但是我们知道如果有两个AAA那么A0A1A_0A_1A0​A1​和A1A0A_1A_0A1​A0​我们是看不出来的,那么就应该排除掉它们的影响
所以这道题的公式就是n!A0!A1!...An!\frac{n!}{A_0!A_1!...A_n!}A0​!A1​!...An​!n!​
其实这道题的本质是卡我们的高精,哎~具体的代码理解在codecodecode里面有详解,你一定会看得懂的

code

#include <cstdio>
#include <cstring>
#define MAXN 30
#define MAX 1000
int n, len;
int A[MAXN];
int res[MAX];void Res_bit () { for ( int i = 0;i < len;i ++ )if ( res[i] > 9 ) {if ( i == len - 1 )len ++;res[i + 1] += res[i] / 10;res[i] %= 10;}
}void Fac ( int x ) {res[0] = x;len = 1;Res_bit();while ( x > 2 ) {//1是不必要乘的,0是不能乘的
//这个条件的下限就是x=3,走进去就变成了2,当x=2时就不必要了 x --;
//大数乘法其实跟竖式乘法是一样的
//我们算A*B是用B的个位依次去乘A的每一位加上B的十位去乘A的每一位的结果...以此类推for ( int i = 0;i < len;i ++ )res[i] *= x;Res_bit ();//每一次都要进行大数进位 }
}void div ( int x ) {//除法也可以用竖式来理解,从最高位开始除
//除不动就往下一位(商0),除得动就把余数传给下一位 for ( int i = len - 1;i >= 0;i -- )if ( res[i] < x ) {//有的人可能会疑问感觉每次除法都只少了一位
//其实不然,在i循环减小时,如果是从最高位开始缩位
//len其实是同步减小了的,上面的进位同理 if ( i == len - 1 )len --;res[i - 1] += res[i] * 10;res[i] = 0;}else {if ( i > 0 )res[i - 1] += ( res[i] % x ) * 10;res[i] = res[i] / x;}
}int main() {while ( scanf ( "%d", &n ) && n ) {int tot = 0;for ( int i = 1;i <= n;i ++ ) {scanf ( "%d", &A[i] );tot += A[i];}Fac ( tot );for ( int i = 1;i <= n;i ++ )for ( int j = 2;j <= A[i];j ++ )div ( j );for ( int i = len - 1;i >= 0;i -- )printf ( "%d", res[i] );printf ( "\n" );memset ( res, 0, sizeof ( res ) );}return 0;
}


我好想写得顺序出了问题,我是fu应该先写生成函数的学习博客,然后再写题解

[指数型生成函数专练]chocolate,红色病毒问题,排列组合,字串数相关推荐

  1. [TJOI2019]唱、跳、rap和篮球(指数型生成函数+NTT+卷积)

    文章目录 题目 题解 code1(NTT) code2(EGF+卷积) 题目 大中锋的学院要组织学生参观博物馆,要求学生们在博物馆中排成一队进行参观.他的同学可以分为四类:一部分最喜欢唱.一部分最喜欢 ...

  2. HDU 2065 红色病毒问题(生成函数)

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  3. HDU 2065 红色病毒 指数型母函数+泰勒公式

    医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶 ...

  4. hdu 2065 红色病毒问题

    Problem Description 医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其 ...

  5. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

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

  6. 指数型生成函数[bzoj3456]城市规划

    前言 打完多项式板子后的第一题+清真的题意 题目相关 题目链接 题目大意 求nnn个点的简单(无重边无自环)无向连通图数目 输出模1004535809(479∗221+1)1004535809(479 ...

  7. 用计算机算出你喜欢吃你喜欢的人,Go for it七年级下学期1-12单元(期末复习)句子翻译专练...

    Go for it七年级下学期1-12单元(期末复习)句子翻译专练 Unit1 1.你的笔友是哪里人? Where is your _________ _______ _________? ( pe ...

  8. 【网络流专练一】UVA五题(UVA12125,UVA11082,UVA10983,UVA1306,UVA10735)

    网络流专练 March of the Penguins 矩阵解压 Matrix Decompressing Buy one, get the rest free The K-League 混合图的欧拉 ...

  9. [SOCI2005]最大子矩阵(DP) + [JXOI2018]守卫(DP) + [CQOI2016]手机号码(数位DP)[各种DP专练]

    DP专练博客 DP专练 T1:最大子矩阵 题目 题解 代码实现 T2:守卫 题目 题解 代码实现 T3:手机号码 题目 题解 代码实现 T1:最大子矩阵 题目 这里有一个n*m的矩阵,请你选出其中k个 ...

最新文章

  1. 【GDKOI2004】使命的召唤
  2. python接口测试第二期_python2 接口测试一般方法.
  3. CVPR 2021 | Facebook提出FP-NAS:搜索速度更快、分类精度更高、性能更好
  4. Tarjan 强连通分量
  5. GPU Gems1 - 26 OpenEXR图像文件格式与HDR(The OpenEXR Image File Format and HDR)
  6. 原来浏览器原生支持JS Base64编码解码
  7. orm2 中文文档 3.2 模型验证器
  8. Office基础操作:Word插入visio图片显示不全
  9. 51单片机-宏晶STC与硬仿真
  10. Android免费获取短信验证码
  11. Charles安装SSL证书失败问题
  12. mysql是正排还是倒排_正排索引与倒排索引的理解
  13. 3d巧用计算机算胆,3D巧用函数公式精准定三胆
  14. 北洋园pt---一个好用的pt网站
  15. 计算机桌面底边出现库如何去掉,桌面图标有蓝底怎么去掉? 去掉桌面图标阴影技巧...
  16. php b2c是什么意思,bto c模式什么意思?
  17. 英语中容易混淆的单词发音: 一
  18. 大数(10^9)求欧拉数
  19. Konva Vue当中的一些技术心得
  20. 云呐-fsu动环监控单元,fsu动环监控单元是什么

热门文章

  1. java 线程 插件_我的第一个Chrome插件:天气预报应用
  2. 两条线段的夹角 cesium_《原本》命题1.10 一条线段可以被分成两条相等的线段
  3. docker pull 私有_【赵强老师】管理Docker镜像
  4. 如何讲页面打入jar包中_如何把我的Java程序变成exe文件?
  5. css-6 df15,webpack 样式文件的代码分割(15)
  6. python回复邮件_在Python中通过Outlook回复电子邮件
  7. java富文本如何转义_富文本编辑器wangEditor中转义字符的问题
  8. Linux中 安装centos-release-scl 报错No package centos-release-scl available.
  9. 7-1 活动选择问题 (25 分)(思路+详解+扩展)宝 今天你AC了吗!!!
  10. 7-47 打印选课学生名单 (25 分)(两种做法)(思路加详解+map+vector做法+最后一个点超时解决)+兄弟们冲丫丫