RPG难题的另一种解法

学好算法的一个关键是要多思考多练习。前段时间做过的一道RPG难题很有意思,让我们来一起看看。

人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深Cole终于知道了原因,原来,LELE最近研究起了著名的RPG难题:
有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.
以上就是著名的RPG难题.
如果你是Cole,我想你一定会想尽办法帮助LELE解决这个问题的;如果不是,看在众多漂亮的痛不欲生的Cole女的面子上,你也不会袖手旁观吧?

简单的说就是用三种颜色涂n个方格,相邻的格子颜色不能相同,且第一个和最后一个格子的颜色不能相同,求全部的满足要求的涂法个数。
其中一种情况就是这样吧RPG难题其实是一个递推求解的题目。其核心代码如下

num[i]=num[i-1]+2*num[i-2];//num[i]为n个格子是染色涂法的个数

知道规律后代码很好写,规律也可以推出来,感兴趣的伙伴的可以百度一下,本篇主要讲解一下我自己的解法哈哈哈

这里需要用到一些高中数学排列组合的知识。我们从第一个格子开始涂色,第一个格子没有任何限制,有红、绿、粉三种颜色选择。第二个格子因为不能与第一个格子颜色相同,只能选择两种颜色,第三个格子不能与第二个格子颜色相同,也只能选择两个颜色。依此类推,第四个格子、第五个格子·······第n个格子也是只能选择两种颜色,那么涂色数就是

num[i]=3*pow(2,n-1;//pow是求次方的函数 3乘n-1个2
//pow函数原型:double pow(double x, double y)其中x值是底数,y值是幂

因为首尾两格也不能同色,所以我们可以用减法,把首尾两格同色的涂色数从上面求出的涂色总数中减去就是我们要的答案。

因为首尾两格颜色相同,所以首格颜色选择后,尾格颜色也就确定了,所以尾格只能选择一种颜色,那么代码好像可以改为

num[i]=3*pow(2,n-1-3*pow(2,n-2;

但我们很快就发现,n个格子中,第n-1个格子颜色本来可以和首格颜色相同也可以不同的,但因为现在第n个格子和首格颜色相同,所以第n-1个格子就不能和首格颜色相同。所以我们要从需要减去的数中再减去第n-1个格子和首格颜色相同的情况。

num[i]=3*pow(2,n-1-3*pow(2,n-2-3*pow(2,n-3));

然后又会发现第n-2个格子不能和首格颜色相同

num[i]=3*pow(2,n-1-3*pow(2,n-2-3*pow(2,n-3-3*pow(2,n-4)));

依此类推
大概就是这样的: a-(b-(c-(d-(e-(f-(g))))))

代码如下

#include<stdio.h>
long long data(long long num, int m);
long long data(long long num, int m)
{
	if(m<=2) return 0;
	num/=2;
	long long yuanzhi=num;
	m--;
	return yuanzhi-data(num,m);
}
int main()
{
	int i,n;
	long long num=1;
	while(scanf("%d",&n)!=EOF)
	{
		for(i=1;i<=n;i++)
		{
			if(i==1) num*=3;
			else num*=2;
		}
		num-=data(num,n);
		printf("%lld\n",num); 
		num=1;
	}
	return 0; 
}

可以试试62个格子时会有多少涂法哈哈哈
在这里插入图片描述

欢迎关注微信公众号算法初探,学习更多的算法知识!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值