牡牛和牝牛

牡牛和牝牛

约翰要带 N 只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛。

牛们要站成一排,但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡牛之间至少要有 K 只牝牛。

请计算一共有多少种排队的方法,所有牡牛可以看成是相同的,所有牝牛也一样,答案对 5000011 取模。

输入格式

一行,输入两个整数 NK

输出格式

一个整数,表示排队的方法数。

数据范围

1N105,
0K<N

输入样例:

4 2

输出样例:

6

样例解释

6 种方法分别是:牝牝牝牝,牡牝牝牝,牝牡牝牝,牝牝牡牝,牝牝牝牡,牡牝牝牡。

 

解题思路

  为了方便这里用1表示牡牛,用0表示牝牛。

  最开始想到用动态规划,然后定义状态f(i,j)表示长度为i且结尾有j个连续的0的所有合法字符串的数量,状态转移方程就是

f(i,j)={u=ki1f(i1,u),  j=0f(i1,j1),j>0

  即使对状态转移的过程进行优化,时间复杂度最好也是O(n2)

  然后参考了y总的状态定义,这种定义方法是真的没想到。定义状态f(i)表示所有长度为i的且以1结尾的合法字符串数量。根据上一个1出现的位置来划分状态,由于两个1之间至少要隔k0,因此上一个1最近要从下标ik1开始。状态转移方程就是f(i)=1+j=1ik1f(j),其中+1是指前面均是0而没有1的情况。

  可以发现每次状态转移都是关于f(i)的一个前缀和,因此可以开个变量来记录f(i)的前缀和,这样状态转移就可以降到O(1),因此整个算法的时间复杂度为O(n)

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10, mod = 5000011;
 5 
 6 int f[N];
 7 
 8 int main() {
 9     int n, m;
10     cin >> n >> m;
11     for (int i = 1, s = 0; i <= n; i++) {
12         f[i] = 1;   // 前面全是0的情况
13         if (i - m - 1 > 0) f[i] = (f[i] + s) % mod; // 至少要隔m个0
14         if (i - m > 0) s = (s + f[i - m]) % mod;    // 累加f[i]的前缀和
15     }
16     int ret = 1;
17     for (int i = 1; i <= n; i++) {  // 最后根据最后一个1出现的位置来统计答案
18         ret = (ret + f[i]) % mod;
19     }
20     cout << ret;
21     
22     return 0;
23 }
复制代码
复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10, mod = 5000011;
 5 
 6 int f[N];
 7 
 8 int main() {
 9     int n, m;
10     cin >> n >> m;
11     for (int i = 1, s = 0; i <= n; i++) {
12         if (i - m - 1 > 0) s = (s + f[i - m - 1]) % mod;
13         f[i] = (f[i] + s + 1) % mod;
14     }
15     int ret = 1;
16     for (int i = 1; i <= n; i++) {
17         ret = (ret + f[i]) % mod;
18     }
19     cout << ret;
20     
21     return 0;
22 }
复制代码

 

参考资料

  AcWing 1307. 牡牛和牝牛(算法提高课):https://www.acwing.com/video/717/

posted @   onlyblues  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-02-01 dfs时间复杂度分析
Web Analytics
点击右上角即可分享
微信分享提示