吃水果
吃水果
个小朋友站成一排,等着吃水果。
一共有 种水果,每种水果的数量都足够多。
现在,要给每个小朋友都发一个水果,要求:在所有小朋友都拿到水果后,恰好有 个小朋友拿到的水果和其左边相邻小朋友拿到的水果不同(最左边的小朋友当然不算数,即最左边的小朋友不包含在 个小朋友内)。
请你计算,一共有多少种不同的分发水果的方案。
输入格式
一行,三个整数 。
输出格式
一个整数,表示合理的分发水果的方案总数量对 取模后的结果。
数据范围
前 个测试点满足 。
所有测试点满足 。
输入样例1:
1 3 3 0
输出样例1:
3
输入样例2:
3 2 1
输出样例2:
2
解题思路
求方案数,想到用动态规划。一开始定义的状态是,表示为前个人分配好水果,且第个人分配到水果,且一共有个人的水果与左边的人不一样。状态转移方程就是
这样做应该是没什么问题的,但很明显这种做法必定会超时,因为状态转移的时间复杂度为。
事实上可以把第二维的状态给优化掉,定义状态表示前个人中恰好有个人拿到的水果与左边的人不一样。根据第个人拿到的水果与左边第个人是否相同来进行状态划分,状态转移方程用到了组合计数
对于第个人拿到的水果与左边第个人相同这种情况,意味着前个人中恰好有个人拿到的水果与左边的人不一样,对应的方案是。又因为第个人与第个人相同,因此这个集合方案数为。
对于第个人拿到的水果与左边第个人不相同这种情况,意味着前个人中恰好有个人拿到的水果与左边的人不一样,对应的方案是。对于前面任何一种方案固定之后(指前个人有个不同),因为第个人与第个人不相同,因此第个人有种选法,因此这个集合方案数为。
可以发现是对原先定义的状态的的优化。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 2010, mod = 998244353; 5 6 int f[N][N]; 7 8 int main() { 9 int n, m, k; 10 scanf("%d %d %d", &n, &m, &k); 11 12 f[1][0] = m; 13 for (int i = 2; i <= n; i++) { 14 for (int j = 0; j <= k && j < i; j++) { 15 f[i][j] = f[i - 1][j]; 16 if (j) f[i][j] = (f[i][j] + f[i - 1][j - 1] * (m - 1ll)) % mod; 17 } 18 } 19 20 printf("%d", f[n][k]); 21 22 return 0; 23 }
还可以通过组合计数来求出答案,答案就是
首先由于第一个人不算数,因此我们从后面的个人选出个人,这个人与其左边相邻的人拿到的水果不同,因此有种选法。
然后第一个人可以选择种水果。个人与其左边相邻的人拿到的水果相同,因此只有种选择,即其左边的人拿什么水果这个人就拿什么水果。个人每个人与其左边相邻的人拿到的水果不同,因此有种选择,个人就有种选择。
最后通过乘法原理得到答案。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int mod = 998244353; 5 6 int qmi(int a, int k) { 7 int ret = 1; 8 while (k) { 9 if (k & 1) ret = 1ll * ret * a % mod; 10 a = 1ll * a * a % mod; 11 k >>= 1; 12 } 13 return ret; 14 } 15 16 int main() { 17 int n, m, k; 18 scanf("%d %d %d", &n, &m, &k); 19 int ret = 1ll * m * qmi(m - 1, k) % mod; 20 for (int i = 1, j = n - 1; i <= k; i++, j--) { 21 ret = 1ll * ret * j % mod * qmi(i, mod - 2) % mod; 22 } 23 printf("%d", ret); 24 25 return 0; 26 }
参考资料
AcWing 4496. 吃水果(AcWing杯 - 周赛):https://www.acwing.com/video/4128/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16630783.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效