滚动数组

https://www.bilibili.com/video/av371396684/


滚动数组是DP中的一种编程思想。简单的理解就是让数组滚动起来,每次都使用固定的几个存储空间,来达到压缩,节省存储空间的作用。起到优化空间,主要应用在递推或动态规划中(如01背包问题)。因为DP题目是一个自底向上的扩展过程,我们常常需要用到的是连续的解,前面的解往往可以舍去。所以用滚动数组优化是很有效的。利用滚动数组的话在N很大的情况下可以达到压缩存储的作用。


当然是用时间去换空间的


举个简单的例子

斐波那契数列:

#include<stdio.h>
int main()
{
     int i;
     long long d[80];
     d[0]=1;
     d[1]=1;
     for(i=2;i<80;i++)
     {
         d[i]=d[i-1]+d[i-2];
     }
     printf("%lld ",d[79]);
     return 0;


上面这个循环d[i]只依赖于前两个数据d[i - 1]和d[i - 2]; 为了节约空间用滚动数组的做法。

#include<stdio.h>
int main()
{
     int i;
     long long d[3];
     d[1]=1;
     d[2]=1;
     for(i=2;i<80;i++)
     {
         d[0]=d[1];
         d[1]=d[2];
         d[2]=d[0]+d[1];
     }
     printf("%lld ",d[2]);
     return 0;

另一种表达形式


#include<stdio.h>
int main()
{
     int i;
     long long d[3];
     d[0] = 1;
     d[1] = 1;
     for(i=2;i<80;i++)
     {
         d[i%3]=d[(i-1)%3]+d[(i-2)%3];
     }
     printf("%lld ",d[79%3]);
     return 0;





二维数组举例

int i, j, d[100][100];
for(i = 1; i < 100; i++)
     for(j = 0; j < 100; j++)
         d[i][j] = d[i - 1][j] + d[i][j - 1];
上面的d[i][j]只依赖于d[i - 1][j], d[i][j - 1];
运用滚动数组

int i, j, d[2][100];
for(i = 1; i < 100; i++)
     for(j = 0; j < 100; j++)
         d[i % 2][j] = d[(i - 1) % 2][j] + d[i % 2][j - 1];//或者 d[i &1 ][j] = d[(i - 1)&1 ][j] + d[i &1][j - 1];



其实还可以改为:


int i, j, d[100];
for(i = 1; i < 100; i++)
     for(j = 0; j < 100; j++)
         d[j] = d[j] + d[j - 1];//


参考:

https://blog.csdn.net/weixin_40295575/article/details/80181756



https://leetcode-cn.com/problems/unique-paths/solution/bu-tong-lu-jing-by-leetcode-solution-hzjf/

为什么官方的代码这么难理解?

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> dp(m,vector<int>(n,1));
        for(int i = 1;i < m;i++)
        {
            for(int j = 1;j < n;j++)
            {
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
                
        }
        
        return dp[m-1][n-1];
    }
};

内存优化后:

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int> pre(n,1),cur(n,1);
        for(int i = 1;i < m;i++)
        {
            for(int j = 1;j < n;j++)
            {
                cur[j] = pre[j] + cur[j - 1];
            }
            swap(pre,cur);
        }
        return pre[n-1];
    }
};

再进一步优化:

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int> dp(n,1);
        for(int i = 1;i < m;i++)
        {
            for(int j = 1;j < n;j++)
            {
                dp[j] += dp[j-1];
            }
        }
        return dp[n-1];
    }
};



dp三角形金字塔中滚动数组;

https://zhuanlan.zhihu.com/p/180443034

原文地址:https://www.cnblogs.com/cute/p/15331471.html