動態規劃——《揹包問題》

474. 一和零(兩種容量的0-1揹包問題)

在計算機界中,咱們老是追求用有限的資源獲取最大的收益。css

如今,假設你分別支配着 m 個 0 和 n 個 1。另外,還有一個僅包含 0 和 1 字符串的數組。數組

你的任務是使用給定的 m 個 0 和 n 個 1 ,找到能拼出存在於數組中的字符串的最大數量。每一個 0 和 1 至多被使用一次。spa

狀態轉移方程:dp[i][j]=(dp[i-s_k_zeros][j-s_k_ones]+1, dp[i][j]);code

int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> dp(m+1,vector(n+1,0));
        for(string& s : strs){
            vector<int> cnt = count(s);
            int zeros=cnt[0],ones=cnt[1];

            for(int i=m;i>=zeros;i--)
                for(int j=n;j>=ones;j--){
                    dp[i][j]=max(dp[i-zeros][j-ones]+1,dp[i][j]);
                }
            }
        return dp[m][n];
    }
    vector<int> count(string& s){
        int z=0,o=0;
        for(int i=0;i<s.length();i++){
            if(s[i]=='0')z++;
            else o++;
        }
        return {z,o};
    }

494. 目標和 (揹包總重可變的固定物品數量的0-1揹包問題)

給定一個非負整數數組,a1, a2, ..., an, 和一個目標數,S。如今你有兩個符號 + 和 -。對於數組中的任意一個整數,你均可以從 + 或 -中選擇一個符號添加在前面。orm

返回能夠使最終數組和爲目標數 S 的全部添加符號的方法數。blog

 

這道題基本上是本身獨立思考想出來的啊哈哈哈哈哈哈遊戲

狀態轉移方程:dp[i][j]=max(dp[i-1][j-nums[i]]+dp[i-1][j+nums[i]],dp[i][j]);leetcode

int findTargetSumWays(vector<int>& nums, int S) {
        int n=nums.size();
        int low=0,up=0;
        for(int i=0;i<nums.size();i++){
            low-=nums[i];
            up+=nums[i];
        }
        if(S<low||S>up)return 0;
        vector<vector<int>> dp(n,vector<int>(4020,0));
        dp[0][nums[0]+1000]++;dp[0][1000-nums[0]]++;
        for(int i=1;i<n;i++){
            for(int j=S+2000;j>=0;j--){
                if(j>=nums[i])
                    dp[i][j]=max(dp[i-1][j-nums[i]]+dp[i-1][j+nums[i]],dp[i][j]);
                else 
                    dp[i][j]=max(dp[i-1][j+nums[i]],dp[i][j]);
            }  
        }
        return dp[n-1][S+1000];
    }

375. 猜數字大小 II

咱們正在玩一個猜數遊戲,遊戲規則以下:資源

我從 1 到 n 之間選擇一個數字,你來猜我選了哪一個數字。字符串

每次你猜錯了,我都會告訴你,我選的數字比你的大了或者小了。

然而,當你猜了數字 x 而且猜錯了的時候,你須要支付金額爲 x 的現金。直到你猜到我選的數字,你纔算贏得了這個遊戲

用動態規劃列舉猜想的全部狀況,每次劃分的左右兩個區間內,假設正確的數字在代價更大的那個區間,找到有最小代價的劃分元素。

int getMoneyAmount(int n) {
        vector<vector<int>> dp(n+1,vector<int>(n+1,0));
        for(int len=2;len<=n;len++){
            for(int start=1;start<=n-len+1;start++){
                int mas=INT_MAX;
                for(int i=start;i<start+len-1;i++){
                    int t=i+max(dp[start][i-1],dp[i+1][start+len-1]);
                    mas=min(mas,t);
                }
                dp[start][start+len-1]=mas;
            }
        }
        return dp[1][n];
    }

待續。。。 

相關文章
相關標籤/搜索