小技巧—滚动数组
小技巧—滚动数组
滚动数组是常见的一种空间优化方式。
应用是递推算法,动态规划(其实现方式是递推)。
举个栗子:
斐波那契数列是递推的一个最好的例子,它的递推公式是:
\[fib_n=fib_{n-1}+fib_{n-2}
\]
也就是说,我们只需要知道n-1和n-2项就能知道第n项,第n项跟前面的所有项都没关系。
所以我们完全可以只开一个长度为3的数组来完成这个过程。
代码:
#include<cstdio>
using namespace std;
int d[3];
int main()
{
int n;
scanf("%d",&n);
d[1]=1,d[2]=1;
for(int i=3;i<=n;i++)
{
d[0]=d[1];
d[1]=d[2];
d[2]=d[0]+d[1];
}
printf("%d",d[2]);
return 0;
}
同理,以0/1背包为例,因为其转移只涉及到了\(dp[i-1]\)和\(dp[i]\)这两维度的状态,所以可以用滚动数组转移。
这种数组的滚动可以通过模运算实现。
滚成多少就模几。
比如上面的代码,也可以这么实现:
#include<cstdio>
using namespace std;
int d[3];
int main()
{
int n;
scanf("%d",&n);
d[1]=1,d[2]=1;
for(int i=3;i<=n;i++)
d[i%3]=d[(i-1)%3]+d[(i-2)%3];
printf("%d",d[n%3]);
return 0;
}