【题解】SP19149 Virus Revisited

本文介绍了一种使用动态规划解决特定细胞扩散问题的方法。通过将问题转化为从原点出发并在特定时间内返回原点的路径计数问题,利用三维数组进行状态转移,实现了O(n^3)的预处理复杂度及O(1)的查询复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

原题传送门

Solution

由于最后求的是原点的细胞数,那么一定是先从原点向外扩展,再扩展回来到达原点。那么我们就可以把答案转化为从原点出发,经过 T ​ T​ T时间回到原点的方案数。

于是我们考虑 d p dp dp,设 f [ i ] [ j ] f[i][j] f[i][j]表示用 i i i个维度,经过 2 j 2j 2j的时间回到原点的方案数(显然奇数时间答案为0)。那么我们考虑对于一个新的维度 i + 1 i+1 i+1和新的时间 2 ( j + k ) 2(j+k) 2(j+k),我们可以从所有时间中,用 2 k 2k 2k时间去第 i + 1 i+1 i+1个维度,于是得到方案 C 2 ( j + k ) 2 k C_{2(j+k)}^{2k} C2(j+k)2k,同时这 2 k 2k 2k时间中,我们又需要分配 k k k的时间向外扩展,剩余 k k k的时间向内扩展,于是又有方案数 C 2 k k C_{2k}^{k} C2kk,所以可以得出转移方程:
f [ i + 1 ] [ j + k ] = f [ i ] [ j ] ∗ C 2 ( j + k ) 2 k ∗ C 2 k k f[i+1][j+k]=f[i][j]*C_{2(j+k)}^{2k}*C_{2k}^{k} f[i+1][j+k]=f[i][j]C2(j+k)2kC2kk
于是进行一遍预处理,复杂度 O ( n 3 ) O(n^3) O(n3),然后 O ( 1 ) O(1) O(1)处理每个询问。总复杂度 O ( n 3 + Q ) O(n^{3}+Q) O(n3+Q)

Code

#include <bits/stdc++.h>
#define ll long long
#define P ((ll)1e9+7)
#define MAX 205
using namespace std;

ll C[MAX][MAX], f[MAX][MAX];

void init(){
	C[0][0] = C[1][1] = 1;
	for(int i = 1; i <= 200; i++){
		C[i][0] = 1;
		for(int j = 1; j <= i; j++){
			C[i][j] = (C[i-1][j-1]+C[i-1][j])%P;
		}
	}
}

int main()
{
	init();
	f[0][0] = 1;
	for(int i = 0; i <= 100; i++){
		for(int j = 0; j <= 100; j++){
			for(int k = 0; k+j <= 100; k++){
				f[i+1][j+k] += f[i][j]*C[2*(j+k)][2*k]%P*C[2*k][k]%P;
				f[i+1][j+k] %= P;
			}
		}
	}
	int t, n, T;
	cin >> t;
	while(t--){
		scanf("%d%d", &n, &T);
		if(T&1) puts("0");
		else
			printf("%lld\n", f[n][T/2]);
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值