小技巧—滾動數組
滾動數組是常見的一種空間優化方式。
應用是遞推算法,動態規划(其實現方式是遞推)。
舉個栗子:
斐波那契數列是遞推的一個最好的例子,它的遞推公式是:
\[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;
}