0
点赞
收藏
分享

微信扫一扫

韦东山老师的从0写RTOS笔记

全栈学习笔记 2023-11-15 阅读 37
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N=50;
LL a[N][5];

void initialize()
{
	a[1][1]=a[1][2]=a[1][3]=a[1][4]=1;
	for(int i=2;i<=45;i++)
	{
		a[i][1]=a[i-1][2]+a[i-1][3];
		a[i][2]=a[i-1][1]+a[i-1][3]+a[i-1][4];
		a[i][3]=a[i-1][1]+a[i-1][2]+a[i-1][4];
		a[i][4]=a[i-1][2]+a[i-1][3];
	}
}

int main()
{
	initialize();
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		LL ans=0;
		ans=a[n][1]+a[n][2]+a[n][3]+a[n][4];
		//printf("%I64d\n",ans);
		cout<<ans<<endl;
	}
	return 0;
}

参考题解: 

1.题解1

2.题解2

根据题意,1旁边只能是2/3,2旁边只能是1/3/4,3旁边只能是1/2/4,4旁边只能是2/3,首先看一下数据范围,2或者3的45次方,2^45/3^45,这个超过了2^31,超过了int的数据范围,所以我们需要使用long long

我们使用一个数组来存储数字。第一个位置可以存1/2/3/4,有四种情况,假设第一个位置存的是1/4,那么第二个位置就只能存2/3,只有两种情况,假设第一个位置存的是2/3,第二个位置有三个数字可以选择。那么我们到底应该怎么考虑这个问题?

(笔者也是初学者,所以如有错误欢迎大佬指正)动态规划(dp)来解决这道题, 动态规划最关键的就是建立状态转移方程。

状态转移方程就是这个,

    a[1][1]=a[1][2]=a[1][3]=a[1][4]=1;
	for(int i=2;i<=45;i++)
	{
		a[i][1]=a[i-1][2]+a[i-1][3];
		a[i][2]=a[i-1][1]+a[i-1][3]+a[i-1][4];
		a[i][3]=a[i-1][1]+a[i-1][2]+a[i-1][4];
		a[i][4]=a[i-1][2]+a[i-1][3];
	}

从第一个元素开始处理,每一次循环,前面的数据是已经被处理过的数据(被计算过),这一点和前缀和的思路有点儿类似。循环结束,所有元素都被处理过了。

输出64位整数,使用%I64d 

 

举报

相关推荐

0 条评论