题目:OpenJudge - 9273:PKU2506Tiling
目录
思路
一道基础的递推题,用二维dp数组存答案(行号→n列)
易得第n块砖有两种情况:①竖放的1*2→dp[i][j]+=dp[i-1][j];
②2*2或横放的1*2→dp[i][j]+=dp[i-2][j];
所以得到了我们的递推公式→ dp[i][j]=dp[i-1][j]+dp[i-2][j]*2
PS:为了方便输出,用dp[i][0]记录答案的位数
代码
#include<iostream>
using namespace std;
int dp[260][333];
void pre()
{
dp[0][0]=dp[0][1]=dp[1][1]=dp[1][0]=dp[2][0]=1;
dp[2][1]=3;
for(int i=3;i<255;i++){
int l=max(dp[i-1][0],dp[i-2][0]);
dp[i][0]=l;
for(int j=1;j<=l;j++)
dp[i][j]=dp[i-1][j]+dp[i-2][j]*2;
for(int j=1;j<=l;j++){
int k=dp[i][j]/10;
dp[i][j]%=10;
dp[i][j+1]+=k;
}
if(dp[i][l+1]) dp[i][0]++;
}
return ;
}
int main()
{
int n;
pre();
while(cin>>n){
for(int i=dp[n][0];i;i--)
cout<<dp[n][i];
cout<<endl;
}
return 0;
}
疑惑
为什么用不到dp[0][0]和dp[0][1]也要定义啊,不定义就是wrong answer 6分,定义了就ac T^T
解答:因为有种特殊情况是输入0💦💦💦所以也可以这样写:
#include<iostream>
using namespace std;
int dp[260][333];
void pre()
{
dp[1][1]=dp[1][0]=dp[2][0]=1;
dp[2][1]=3;
for(int i=3;i<255;i++){
int l=max(dp[i-1][0],dp[i-2][0]);
dp[i][0]=l;
for(int j=1;j<=l;j++)
dp[i][j]=dp[i-1][j]+dp[i-2][j]*2;
for(int j=1;j<=l;j++){
int k=dp[i][j]/10;
dp[i][j]%=10;
dp[i][j+1]+=k;
}
if(dp[i][l+1]) dp[i][0]++;
}
return ;
}
int main()
{
int n;
pre();
while(cin>>n){
if(!n) cout<<"1";
else for(int i=dp[n][0];i;i--)
cout<<dp[n][i];
cout<<endl;
}
return 0;
}
有用的话就点赞评论收藏嗷!!