CF118D Caesar's Legions

As(这个神秘的男人)给我随机分到的题
题意:
给出n1个1,n2个2,给出k1和k2代表连续的1和2的最大长度,问能够构造的合法的不同串的数量。
一开题看数据范围就知道不用优化,于是直接给Cy神仙说是红题(LuoGu紫题肯定是被恶意评分了),于是又被Zxh大神仙嘲讽了
真的不难,计数Dp,方程易推
f [ a ] [ b ] [ c ] [ d ] f[a][b][c][d] f[a][b][c][d]表示对于前a个士兵,第a个是兵种(0为步兵,1为骑兵),末尾有连续c个该兵种,总共有d个该兵种
然后可知如果第a个兵种的方案可以由第a-1个兵种相同且满足规则(总数不超过且连续数不超过)或第a-1个兵种不同的方案数相加得到
于是就很好推了
初始化 f [ 1 ] [ 0 ] [ 1 ] [ 1 ] = f [ 1 ] [ 1 ] [ 1 ] [ 1 ] = 1 f[1][0][1][1]=f[1][1][1][1]=1 f[1][0][1][1]=f[1][1][1][1]=1
然后从2开始做
(由于本来看的是题目大意,然后不知道要取模而错了两次的弱智Code_Note)
附上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MAXN 210
#define MOD 100000000
int n, m, a, b;
ll ans;
ll f[MAXN][2][MAXN][MAXN];
inline int read() {
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (s == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}
int main() {
	n = read(), m = read();
	a = read(), b = read();
	f[1][0][1][1] = 1;
	f[1][1][1][1] = 1;
	for (register int i = 2; i <= n + m; i++) {
		for (register int j = 2; j <= a; j++)
			for (register int k = 1; k <= n; k++)
				(f[i][0][j][k] += f[i - 1][0][j - 1][k - 1]) %= MOD;
		for (register int j = 2; j <= b; j++)
			for (register int k = 1; k <= m; k++)
				(f[i][1][j][k] += f[i - 1][1][j - 1][k - 1]) %= MOD;
		for (register int j = 1; j <= a; j++)
			for (register int k = 1; k <= n; k++)
				if (i - k >= 0)
					(f[i][1][1][i - k] += f[i - 1][0][j][k]) %= MOD;		
		for (register int j = 1; j <= b; j++)
			for (register int k = 1; k <= m; k++)
				if (i - k >= 0)
					(f[i][0][1][i - k] += f[i - 1][1][j][k]) %= MOD;			
	}
	for (register int i = 1; i <= a; i++) 
		(ans += f[n + m][0][i][n]) %= MOD;;
	for (register int i = 1; i <= b; i++) 
		(ans += f[n + m][1][i][m]) %= MOD;;
	printf("%lld", ans);
	return 0;
}

这是我写的最认真的一次题解了!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值