2020 算法上机赛 C1 - F 超体 - 简单版
题目描述
要么永生,要么繁殖。
在环境舒适的 \(X\) 星球,细胞们选择了繁殖,并且把知识一代一代传承下去。
在 \(t=1\) 秒时,有一个新生的细胞在混沌中诞生了。
- 对于每个细胞,当它诞生 \(a\) 秒后就会变得成熟。
- 每个成熟的细胞每秒都会分裂一次(包括它刚刚成熟的那一时刻)。每次分裂会产生一个新生细胞。
- 每个细胞在它的成熟期只能分裂 \(b\) 次。在最后一次分裂之后,细胞会立刻进入衰老期。
- 进入衰老期再过 \(c\) 秒后,细胞会立刻死亡。
在 \(t=T\) 秒时,你能计算出 \(X\) 星球一共有多少活着的细胞吗?
输入
一行,仅四个整数,相邻整数间由一个空格隔开,四个整数分别是上文中的 \(a,b,c,T\)
输出
一行,仅一个整数,在 \(t=T\) 秒时活着的细胞的总数。保证答案在 \(long long\) 范围内。
输入样例1
1 1 1 2
输出样例1
2
输入样例2
1 1 1 3
输出样例2
3
输入样例3
1 1 1 5
输出样例3
3
数据范围
\(a,b,c,T∈[1,10]\)
样例解释
圆圈 / 方格内的数字代表细胞的年龄。
每一横行对应着一个细胞在各个时刻的状态。如最下面那一横行代表 \(t=1\) 时刻从天而降的那个细胞在各个时间的状态。
\(t=1\) 时刻有一个新生细胞,\(t=2\) 时它成熟并进行一次分裂新生成了一个新细胞,\(t=3\) 时它进入老年期,它刚刚分裂产生的那个细胞成熟并且又分裂出一个新细胞,以此类推...
Hint
什么波那契?
做法
出题人的良心很坏, Hint 是误导人的
注意到 \(a,b,c,T\) 的范围都很小,所以其实按照题目的意思,把所有年龄的细胞存到 dp[N]
里面,然后模拟就可以了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
inline int read() {
int q=0,w=1;char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c))q=q*10+c-'0',c=getchar();
return w*q;
}
typedef long long ll;
ll dp[233][2], ans;
int a, b, c, T;
int pre, now;
int main() {
dp[1][1] = 1; pre = 1; now = 0;
a = read(); b = read(); c = read(); T = read() - 1;
a += 1; b += a - 1; c += b;
for(int i = 1;i <= T; ++i, swap(pre, now)) {
for(int j = 1;j <= c; ++j)
dp[j][now] = 0;
for(int j = 2;j <= c; ++j)
dp[j][now] = dp[j - 1][pre];
for(int j = a;j <= b; ++j)
dp[1][now] += dp[j][now];
}
for(int i = 1;i <= c; ++i)
ans += dp[i][pre];
cout << ans << endl;
return 0;
}