zoukankan      html  css  js  c++  java
  • 滚动数组

    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

  • 相关阅读:
    CentOS 6.x 系统安装选项说明
    MySQL表的操作
    6月13号
    6月11号
    6月10号
    6月9号
    6月6
    day27
    day 28
    day 29
  • 原文地址:https://www.cnblogs.com/cute/p/15331471.html
Copyright © 2011-2022 走看看