原题链接

题目大意:

有来自三个地区的人各a,b,c位,他们排成了一排。请问有多少种不同类型的排法,使得相邻的人都来自不同的地区

\(a,b,c<=200\)

答案取模

题解##

弱弱的标程解法##

设\(f[i][j][k][l]\)表示三种人各排了\(i\)、\(j\)、\(k\)个,最后一个人是l类

那么转移就很显然了,枚举下一个非\(l\)人即可

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 205,P = 2001611;
int f[maxn][maxn][maxn][3],a,b,c;
int main(){
scanf("%d%d%d",&a,&b,&c);
f[1][0][0][0] = f[0][1][0][1] = f[0][0][1][2] = 1;
for (int i = 0; i <= a; i++)
for (int j = 0; j <= b; j++)
for (int k = 0; k <= c; k++)
for (int l = 0; l <= 2; l++){
if (i < a && l != 0)
f[i + 1][j][k][0] = (f[i + 1][j][k][0] + f[i][j][k][l] * (i + 1) % P) % P;
if (j < b && l != 1)
f[i][j + 1][k][1] = (f[i][j + 1][k][1] + f[i][j][k][l] * (j + 1) % P) % P;
if (k < c && l != 2)
f[i][j][k + 1][2] = (f[i][j][k + 1][2] + f[i][j][k][l] * (k + 1) % P) % P;
}
printf("%d\n",(f[a][b][c][0] + f[a][b][c][1] + f[a][b][c][2]) % P);
return 0;
}

更优秀的解法##

std解法考虑往队尾插人,需要设置四维状态

我们考虑只设置三维状态,运用记忆化搜索

同样设\(f[i][j][k]\)表示三种人各排了\(i\)、\(j\)、\(k\)个

可以发现三种人是等价的,人数互换不影响结果

所以我们只考虑\(i <= j <= k\)

转移时,为使状态最终能转移至初始状态,我们考虑人数最多的\(k\)

我们在最后合法的队形中抽出\(k\)中的一个人,会出现两种情况:

①最后的队列还是一个合法队列

②最后的队列不合法,而且仅有原来抽出的位置有两个相同的人相邻

那么就可以转移了

①如果合法,就有\(f[i][j][k - 1]\)中队形,其中有\(i + j - k + 2\)个可插入位置,总共有\(f[i][j][k - 1] * (i + j - k + 2)\)种方案

②如果不合法,要么是\(i\)相邻,要么是\(j\)相邻,

以\(i\)相邻为例,我们如果把相邻的两个人看做一个人,那么这个状态就又是合法的了,有\(f[i - 1][j][k]\)种方案,而\(i\)中任意选两个人有序组合,有\(P_{i}^{2}\)中方案,故对\(i\)总共有\(f[i - 1][j][k - 1] * P_{i}^{2}\)中方案

\(j\)类似

考虑边界,当出现0时,

①两个0,即只剩一种人了,当且仅当人数为1时方案数为1,否则为0

②一个0,即剩余两种人,如果两种人人数只差超过了1,方案数为0,否则两种人之间的位置关系一定是交替的,用排列数计算即可

具体实现参考代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 205,maxm = 100005,INF = 1000000000,P = 2001611;
LL f[maxn][maxn][maxn],fac[maxn];
bool vis[maxn][maxn][maxn];
void order(LL& x,LL& y,LL& z){
if (x > y) swap(x,y); if (x > z) swap(x,z); if (y > z) swap(y,z);
}
LL F(LL x,LL y,LL z){
order(x,y,z);
if (vis[x][y][z]) return f[x][y][z]; //记忆化
vis[x][y][z] = true;
LL& ff = f[x][y][z];
if (y == 0) return ff = (z == 1); //边界
if (x == 0){
if (z == y) return ff = fac[z] * fac[y] % P * 2 % P;
if (abs(z - y) == 1) return ff = fac[z] * fac[y] % P;
return 0;
}
return ff = (F(x,y,z - 1) * (x + y - z + 2) % P + x * (x - 1) % P * F(x - 1,y,z - 1) % P + y * (y - 1) % P * F(x,y - 1,z - 1) % P) % P;
}
int main(){
fac[0] = 1;
for (int i = 1; i <= 200; i++) fac[i] = fac[i - 1] * i % P; //预处理阶乘
LL a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
printf("%lld\n",F(a,b,c));
return 0;
}

Mychael原创题 洛谷T23923 Mychaelの水题 【题解】的更多相关文章

  1. [洛谷U22157]刷水题(数位dp)(hash)

    题目背景 做正经题是不可能做正经题的,这辈子都不可能做正经题的,毒瘤题又不会做毒瘤题,就是水题这种东西,才维持了蒟蒻的信心: 题目描述 这里有N+1 道水题,编号分别为0 ~N+1 ,每道水题都有它自 ...

  2. [洛谷P4626]一道水题 II

    题目大意:求$lcm(1,2,3,\cdots,n)\pmod{100000007}$,$n\leqslant10^8$ 题解:先线性筛出质数,然后求每个质数最多出现的次数,可以用$\log_in$来 ...

  3. 洛谷P1540 机器翻译 水题 模拟

    注意一下细节,尤其是更新minv时不要更新错. Code: #include<vector> #include<iostream> #include<cstdio> ...

  4. 洛谷 P1190 接水问题 题解

    P1190 接水问题 题目描述 学校里有一个水房,水房里一共装有 \(m\) 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为1. 现在有 \(n\) 名同学准备接水,他们的初始接水顺序已经确 ...

  5. 洛谷 P2791 幼儿园篮球题

    洛谷 P2791 幼儿园篮球题 https://www.luogu.org/problemnew/show/P2791 我喜欢唱♂跳♂rap♂篮球 要求的是:\(\sum_{i=0}^kC_m^iC_ ...

  6. 洛谷 P2220 [HAOI2012]容易题 数论

    洛谷 P2220 [HAOI2012]容易题 题目描述 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 有一个数列A已知对于所有的A[i]都是1~n的自然数 ...

  7. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  8. 洛谷P1783 海滩防御 分析+题解代码

    洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...

  9. 洛谷P4047 [JSOI2010]部落划分题解

    洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...

随机推荐

  1. 【数据库-Azure SQL Database】SQL Server 如何将数据库备份到 Azure Storage

    打开本地的 SQL Server Management Studio.首先创建 Credentials.命令如下:   IF NOT EXISTS (SELECT * FROM sys.credent ...

  2. .NET 通过 NPOI 操作 Excel

    目录 .NET 通过 NPOI 操作 Excel 第一步:通过 NuGet 获取 NPOI 包并引入程序集 第二步:引入 NPOI 帮助类 第三步:在程序中调用相应的方法对数据进行导出导入操作 将 D ...

  3. TLint for 虎扑体育应用源码项目

    虎扑非官方客户端TLint全新Material Design设计,简洁美观支持论坛全部操作,浏览帖子.点亮.回复.引用.收藏等多项个性化设置(不同主题,不同阅读模式) TLint For 虎扑体育 更 ...

  4. UVA1001 Say Cheese (dijkstra)

    如果没有洞,那么任意两点的最短距离就是直线距离,洞里是瞬间的,所以看成一个点就行了(其实点也可以当作半径为0的洞来处理),洞到洞的最短距离都是圆心距离减去半径.剩下的就是求单源最短路径,是完全图,用不 ...

  5. 一个制作Xcode5插件的模板

    原Github地址:https://github.com/kattrali/Xcode5-Plugin-Template 安装将 本工成复制到~/Library/Developer/Xcode/Tem ...

  6. ucosii(2.89)mbox 应用要点

    OSMboxCreate(void *msg)     当创建一个mbox时候,消息邮箱允许(任务或者中断)向其他一个或者几个任务发送消息.初始化msg指向消息邮箱中的消息. void*OSMboxP ...

  7. CPP-网络/通信:COM

    ))//打开串口 { ) { CloseCom();//关闭串口 break; } //添加处理代码. } //最后关闭串口 CloseCom();//关闭串口

  8. MFC学习小结

    2019/1/13 视频来源 一.   MFC框架中一些重要的函数 1. InitInstance函数 应用程序类的一个虚函数,MFC应用程序的入口.初始化的作用. 2. PreCreateWindo ...

  9. C++系统学习之八:IO库

    新的C++标准中有三分之二的内容都是描述标准库.接下来重点学习其中几种核心库设施,这些是应该熟练掌握的. 标准库的核心是很多容器类(顺序容器和关联容器等)和一簇泛型算法(该类算法通常在顺序容器一定范围 ...

  10. [CODEVS] 2189 数字三角形W

    数字三角形 要求走到最后mod 100最大 可达性DP(好像是这样叫) 用bool数组f[i][j][k]表示 位置(i,j)能否得到k(mod 100意义下) 转移条件 f[i][j][k]=f[i ...