初始化法求斐波那契数列
初始化法
先进行初始化操作,在进行O(1)复杂度的查找;
#include <iostream>
#include <cstdio>
using namespace std;
static const long MAX =100000;
int f[MAX];
void init(int n){
f[0]=1,f[1]=1;
for(int i=2;i<n;i++){
f[i]=f[i-1]+f[i-2];
}
}
int main(){
init(MAX);
int n;
while(scanf("%d",&n)!=EOF){
printf("%d\n",f[n]);
}
return 0;
}
记忆化递归求斐波那契数列
记忆化搜索法
先初始为-1,再对输入的n进行查找,如果dp[n]已经储存了,就返回dp[n]
如果没有存储,就用递归的方法求
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
static const long MAX =100000;
int dp[MAX];
int fib(int n){
if(n==0||n==1)return 1;
if(dp[n]!=-1)return -1;
return dp[n]=fib(n-1)+fib(n-2);
}
int main(){
memset(dp,-1,sizeof(dp));
int n;
while(scanf("%d",&n)!=EOF){
printf("%d\n",fib(n));
}
return 0;
}
状态转移方程
01背包问题
二维数组:
for(int i=1;i<=物品的数目;i++){
for(int j=1;j<=背包的容量;j++){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
}
之所以从1开始,是因为有个i-1,为了不产生意外,所以w,v,dp数组都是从1开始
而一位数组可以都从0开始
一维数组:
for(int i=0;i<物品的数目;i++){
for(int j=最大容量;j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
因为容量是一个整数,所以需要把w数组全部变成整数型,可以在小数的基础上乘10^n,最后dp求出最值之后,再除以10^n;