动态规划——滚动数组
动态规划有一个很重要的特点:无后效性,意思是当前状态的决策不受过去决策的影响。所以当状态很多时,我们不必去保存所有的状态,这样很占用内存,我们只需保存与当前决策有关的状态即可。
下面以斐波那契数列为例。求f[100]时,我们通常时利用是开一个100的数组空间。可是f[100]=f[99]+f[98],其只与它的前两个状态有关,此外,像f[i]=f[i-1]+f[i-2],每一个数都只和它的前两个状态有关,所以我们实际上只需要开一个3的空间,就可以通过不断的迭代,只保留与当前决策有用的状态而之前的无用信息全部舍去。这就是滚动数组。下面上两个斐波那契代码
普通做法
#include<iostream> #include<cstdio> using namespace std; int f[100]; int ff(int n) { f[0] = 0; f[1] = 1; f[2] = 1; for(int i = 3; i <= n; ++i) f[i] = f[i - 1] + f[i - 2]; return f[n]; } int main() { int t, n; scanf("%d", &t); while(t--) { scanf("%d", &n); printf("%d\n", ff(n)); } return 0; }
滚动数组
#include<cstdio>
using namespace std;
int f[3];
int ff(int n)
{
f[1] = 0;
f[2] = 1;
for(int i = 2; i <= n; ++i)
{
f[0] = f[1];
f[1] = f[2];
f[2] = f[0] + f[1];
}
return f[2];
}
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
printf("%d\n", ff(n));
}
return 0;
}