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;
}
posted @ 2020-12-31 10:58  Withinlover  阅读(80)  评论(0编辑  收藏  举报