#include <bits/stdc++.h>
using namespace std;
int w[50];
int i = 1;
int ans = 0;
//Process exited after 1.564 seconds with return value 0 动态规划 40 的时间
//Process exited after 3.752 seconds with return value 0 暴力dfs
//结果都是一致的
void dfs(int x)//放x个数字 暴力dfs 应该是可以优化的
{
w[0]=1;
if (x==0)
{
// for (int j = 1;j<i;j++) cout << w[j] <<" ";
// cout << endl;
ans ++;
return;
}
if (w[i-1]==0)
{
w[i++] = 1;
dfs(x-1);
i--;
}
if (w[i-1]==1)
{
w[i++]=0;
dfs(x-1);
i--;
w[i++]=1;
dfs(x-1);
i--;
}
}
int dp[30][2];
//动态转移方程
// dp[i][0]=dp[i-1][1]
// dp[i][1]=dp[i-1][0]+dp[i-1][1]
int main()
{
int N;
cin >> N;
dfs(N);
cout << ans << endl;
int dp[60][2];// f[i][0]=f[i-1][1] f[i][1]=f[i-1][0]+f[i-1][1]
dp[1][0] = 1;
dp[1][1] = 1;
for (int i = 2;i<=N;i++)//表示已经放了几位数
{
for (int j = 0;j<=1;j++)//表示当前数字
{
if (j==0) dp[i][j]=dp[i-1][1];
if(j==1) dp[i][j]=dp[i-1][0]+dp[i-1][1];
}
}
cout << dp[N][1]+dp[N][0];
return 0;
}
在这道题中 两种方法都不会超时,但是很明显动态规划更好一点,而且显得很装bi ,思想就是根据当前数字是0还是1进行分类讨论,如果当前为0,那么前面一个数字必须是1,同样,假如当前为1,那就不要在乎前面一个数字是0还是1,每一步都这样严格执行,可以得到整体是符合题意的。
dp[i][j]就是代表放入了i个数字而且当前数字为j;
利用滚动数组,也可以将数组压缩成一维的;
#include<iostream>
using namespace std;
int main(){
int n,dp[20];
dp[0]=2;dp[1]=3;
for(int i=2;i<20;i++) dp[i]=dp[i-1]+dp[i-2];
cin>>n;
cout<<dp[n-1];
}
形式会更简单 同样效率也会很高 查询O(1)。
不理解的或者有错误的可以在下面评论。