zoukankan      html  css  js  c++  java
  • 01 背包基础

    2017-09-03 11:39:16

    writer:pprp

    以很简单的一个动态规划问题为引入:

    从左上角到右下角走过的路径和最大,问你最大为多少?

    1、可以想到普通的dp

    状态转移为: dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + arr[i][j];

    2、采用滚动数组的方式-节约了不必要的空间

    状态转移为:dp2[i%2][j] = max(dp2[(i+1)%2][j],dp2[i%2][j-1]) + arr[i][j];

    3、采用一维阵列的方式更加节省空间

    状态转移为:dp3[j] = max(dp3[j],dp3[j-1]) + arr[i][j];

    图解:

    代码如下:

    /*
    @theme:空间优化,滚动数组,只使用一维阵列
    @writer:pprp
    @begin:10:45
    @end:11:36
    @declare:从左上角到右下角的总和最多为多少?
    @error:
    @date:2017/9/3
    */
    
    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 100;
    int arr[maxn][maxn];
    int dp[maxn][maxn];
    int dp2[2][maxn];
    int dp3[maxn];
    int n, m;
    
    void init()
    {
        freopen("in.txt","r",stdin);
        memset(dp,0,sizeof(dp));
        memset(arr,0,sizeof(arr));
        memset(dp2,0,sizeof(dp2));
        memset(dp3,0,sizeof(dp3));
        cin >> n >> m;
        for(int i = 0 ; i < n; i++)
        {
            for(int j = 0 ; j < m ; j++)
            {
                cin >> arr[i][j];
            }
        }
    }
    
    //普通简单dp
    int fun1()
    {
        dp[0][0] = arr[0][0];
        for(int i = 1; i < n ; i++)
        {
            dp[i][0] += arr[i][0] + dp[i-1][0];
        }
        for(int j = 1; j < m ; j++)
        {
            dp[0][j] += arr[0][j] + dp[0][j-1];
        }
        for(int i = 0 ; i < n ; i++)
        {
            for(int j = 0 ; j < m ; j++)
            {
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + arr[i][j];
            }
        }
    
        return dp[n-1][m-1];
    }
    
    //滚动数组
    int fun2()
    {
        dp2[0][0] = arr[0][0];
        for(int i = 1 ; i < m ; i++)
            dp2[0][i] += dp2[0][i-1] + arr[0][i];
        for(int i = 0  ; i < n ; i++)
        {
            for(int j = 0 ; j < m ; j++)
            {
                dp2[i%2][j] = max(dp2[(i+1)%2][j],dp2[i%2][j-1]) + arr[i][j];
            }
        }
        return dp2[(n-1)%2][m-1];
    }
    
    
    //一维阵列
    int fun3()
    {
        for(int i = 0 ; i < n ; i++)
        {
            dp3[0] = arr[i][0];
            for(int j = 1 ; j < m ; j++)
            {
                dp3[j] = max(dp3[j],dp3[j-1]) + arr[i][j];
            }
        }
        return dp3[m-1];
    }
    
    int main()
    {
        init();
        cout << fun1() << endl;
        cout << "-----" << endl;
        for(int i = 0 ; i < n ; i++)
        {
            for(int j = 0 ; j < m ; j++)
                cout << dp[i][j] << " ";
            cout << endl;
        }
        cout << endl;
        cout << fun2() << endl;
        cout << "-----" << endl;
        for(int i = 0 ; i < m ; i++)
        {
            cout << dp2[0][i] << " ";
        }
        cout << endl;
        for(int i = 0 ; i < m ; i++)
        {
            cout << dp2[1][i] << " ";
        }
        cout << endl;
        cout << "-----" << endl;
        cout << fun3() << endl;
    
    
        return 0;
    }
  • 相关阅读:
    【leetcode】106. Construct Binary Tree from Inorder and Postorder Traversal
    【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
    【leetcode】236. Lowest Common Ancestor of a Binary Tree
    【leetcode】235. Lowest Common Ancestor of a Binary Search Tree
    【leetcode】352. Data Stream as Disjoint Intervals
    【leetcode】897. Increasing Order Search Tree
    【leetcode】900. RLE Iterator
    BEC listen and translation exercise 26
    BEC listen and translation exercise 25
    BEC listen and translation exercise 24
  • 原文地址:https://www.cnblogs.com/pprp/p/7469200.html
Copyright © 2011-2022 走看看