YbtOJ 递推算法课堂过关 例5 平铺方案【递推(简单DP)】

在这里插入图片描述


思路

首先读题可得设 f [ i ] f[i] f[i] 表示 2 ∗ i 2*i 2i 时的方案数。
因为边最长是2,所以考虑从 f [ i − 1 ] f[i-1] f[i1] f [ i − 2 ] f[i-2] f[i2] 转移。
i − 2 i-2 i2 时的情况:
在这里插入图片描述
i − 1 i-1 i1 时只有可能有一条竖着的,所以直接继承 f [ i − 1 ] f[i-1] f[i1]
当然此时存在了重复, i − 2 i-2 i2 的两条竖着的情况和 i − 1 i-1 i1 的情况发生了冲突,
所以直接把 i − 2 i-2 i2 的情况剔除即可。
需要高精度。

C o d e Code Code

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long f[300][101];
int n,m;
void gjc(int x)
{
    
    
	int jw=0;
	for(int i=1; i<=f[x-2][0]+1; i++)
	 {
    
    
	 	f[x][i]=(f[x-2][i]*2)%10+jw;
	 	jw=(f[x-2][i]*2)/10;
	 }
	if(f[x][f[x-2][0]+1]!=0)
	  f[x][0]=f[x-2][0]+1;
	else
	  f[x][0]=f[x-2][0];
}
void gjj(int x)
{
    
    
	int jw=0;
	for(int i=1; i<=f[x][0]+1; i++)
	 {
    
    
	 	int g=(f[x][i]+f[x-1][i]+jw);
	 	f[x][i]=g%10;
	 	jw=g/10;
	 }
	if(f[x][f[x][0]+1]!=0)
	  f[x][0]=f[x-1][0]+1;
}
int main()
{
    
    
	f[1][1]=1,f[2][1]=3,f[1][0]=1,f[2][0]=1;
	for(int i=3; i<=250; i++)
	 {
    
    
	   gjc(i);
	   gjj(i);
	 }
	//f[i]=f[i-2]*2+f[i-1];
	while(cin>>n)
	 {
    
    
	 	int i=f[n][0];
	 	while(f[n][i]==0)
	      i--;
	 	for(int i=f[n][0]; i>=1; i--)
	 	   cout<<f[n][i];
	 	cout<<endl;
	 }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/111705146