1161--骨牌--2023/1/9

首先呢这个题目是一个递推的题目。

对于这个题目,我们先来看一个简单的版本:

Problem - 2046

对于这个题目,大家可能觉得会很显然,因为通过画图,然后总结一下,就会比较容易地找到递推的规律。

我们把n=2、n=3、n=4的图画出来后可以发现,图分为两类,一类是最后一列是竖列,那么f[n-1]是排列好的,另一种是最后两列都是横列,那么f[n-2]排列好的。至此,我们就可以推出规律了(f[n]=f[n-1]+f[n-2])。

那么我们现在来分析这个题目。

首先我们用f[n]来表示长为n时的答案。那么现在我们来思考如何列出来递推公式呢?

为了解决这个问题,首先我们可以先画画图,通过思考易知当n为奇数的时候,肯定是不可能有铺排的方案的。当n为偶数的时候,f[2]=3,f[4]=11.....

画图如下:

在画n=4的时候,通过观察知道左边9个是由f[2]*f[2]得来的,然后右边两个是比较特殊的,右边两个是不可以分开的(就像一个整体一样)。因此对于f[n]的递推关系,我们也采用可以拆分和不可以拆分来写。

首先f[n]=f[n]+f[n-2]*f[2]也就是在长度为n-2的基础上右边是长度为二的砖块,这个是可以拆分的情况。

对于不可以拆分的部分,首先不可以拆分的砖块最短都要为4,因此f[n]=(f[n-4]+f[n-6]+.....+f[0])*2

不可以拆分的右边其实就是两种,对于这个不可拆分的理解就是,我把f[n]看成是f[n-4]和一个长度为4的砖头组合在一起的,然后长度为4的这个砖头是不可以拆分的,我们还可以把他弄成是f[n-6]和一个不可拆分的长度为6的砖头构成的,直到f[0]和一个长度为n的不可拆分的砖头构成。

比如长度为6的时候不可拆分的图:

长度为8的时候为:

而且不可拆的情况都只有两种。

因此综上:f[n]=f[n-2]*f[2]+2*(f[n-4]+f[n-6]+...+f[0])其中令f[0]=1哦

上代码喽:

#include <stdio.h>
#include <math.h>
#include <string.h>
#define ll __int64
#define num 100003

ll f[1005];

//比较暴力的实现方法,但是当n比较大的时候,比如n的范围如果为1e6的话
//两重循环的话就会超时
//那么思考一下,如果n的范围为1e6的话,如何写呢?
void init(){
	f[0]=1;f[2]=3;
	for(int i=3;i<=1000;i++){
		if(i%2) f[i]=0;
		else{
			f[i]=(f[i-2]*f[2])%num;
			for(int j=i-4;j>=0;j-=2){
				f[i]=(f[i]+(f[j]*2)%num)%num;
			}
		}
	}
}

int main(){
	init();
	int n;
	while(scanf("%d",&n)!=EOF && n){
		printf("%I64d\n",f[n]);
	} 
	return 0;
}

 如果n的范围比较大的话,f[n-4]+f[n-2]+...+f[0]可以用前缀和的思想来实现哦,只要用一个变量不断更新就好。

因此代码见下:

#include <stdio.h>
#include <math.h>
#include <string.h>
#define ll __int64
#define num 100003

ll f[1005];

void init(){
	f[0]=1;f[2]=3;
	ll sum=1;//开始初始化为sum=f[0]
	//然后不断更新这个值哦
	for(int i=3;i<=1000;i++){
		if(i%2) f[i]=0; //如果是奇数的话,比较容易想到就是这种情况为0
		else{
			f[i]=((f[i-2]*f[2]%num)+2*sum%num)%num;
			sum=(sum+f[i-2])%num;
		}
	}
}

int main(){
	init();
	int n;
	while(scanf("%d",&n)!=EOF && n){
		printf("%I64d\n",f[n]);
	} 
	return 0;
}

ok,我们明天再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值