第一种方法:暴力搜索DFS
#include <iostream>
using namespace std;
int dfs(int n)
{
if(n == 1) return 1;
else if(n == 2) return 2;
else return dfs(n-1)+dfs(n-2);
}
int main()
{
int x; cin>>x;
cout<<dfs(x)<<endl;
return 0;
}
显然如果数据范围大一点的话 就过不了 !!! 所以拿出我们的神器------>记忆化搜索
第二种方法:记忆化搜索
#include <iostream>
using namespace std;
const int N = 10000;
int mem[N],t;
int dfs(int n)
{
if(mem[n]) return mem[n];
int sum = 0;
if(n == 1) sum = 1;
else if(n == 2) sum = 2;
else sum = dfs(n-1)+dfs(n-2);
mem[n] = sum;
return sum;
}
int main()
{
int t; cin>>t;
cout<<dfs(t)<<endl;
return 0;
}
第三种:递推
#include <iostream>
using namespace std;
const int N = 40;
int f[N],n;
int main()
{
f[1] = 1,f[2] = 2;
cin>>n;
if(n == 1 || n == 2)
{
cout<<f[n]<<endl;
return 0;
}
for(int i=3;i<=n;i++)
{
f[i] = f[i-1]+f[i-2];
}
cout<<f[n]<<endl;
return 0;
}
记忆化搜索
#include <bits/stdc++.h>
using namespace std;
const int N = 111111;
int t,n,p[N],mem[N];
int dfs(int x)
{
if(mem[x]) return mem[x];
int sum = 0;
if(x>n) sum=0;
else sum = max(dfs(x+1),dfs(x+2)+p[x]);
mem[x] = sum;
return sum;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
memset(mem,0,sizeof mem);
int cnt = dfs(1);
printf("%d\n",cnt);
}
return 0;
}
改为递推:
状态转移方程为:f[i] = max(f[i+1], f[i+2] + p[i])
#include <bits/stdc++.h>
using namespace std;
const int N = 111111;
int t,n,p[N],f[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
memset(f,0,sizeof f);
for(int i=n;i>=1;i--)
{
f[i] = max(f[i+1],f[i+2]+p[i]);
// 逆序遍历数组p,计算f数组的值。
// f[i]表示从第i个数开始,取若干个连续的数(至少一个),使得这些数的和最大。
// 状态转移方程为:f[i] = max(f[i+1], f[i+2] + p[i])
// 这里的思路是考虑当前位置i是否取数,如果取数,则下一个位置i+1不能取数,因此考虑f[i+2] + p[i]。
}
printf("%d\n",f[1]);
}
return 0;
}
继续空间优化: !!! 待续
2.数字三角形!!!