算法分析與設計課程作業第九周#1#2#3

算法分析與設計課程作業第九周#1#2#3

這周我選了3道有關動態規劃的題目來做。

718. Maximum Length of Repeated Subarray

Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays.
Example 1:
Input:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
Output: 3
Explanation:
The repeated subarray with maximum length is [3, 2, 1].

Note:
1 <= len(A), len(B) <= 1000
0 <= A[i], B[i] < 100

思路:

用len[i][j] 表示以A[i]與B[j]爲結尾的重複子數組的長度,則所求是max{len[i][j]|0 <= i < sizeA, 0 <= j < sizeB}
狀態轉移式爲:
len[i][j] = A[i]==B[j]?len[i-1][j-1] +1:0。

代碼:

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int sizeA = A.size();
        int sizeB = B.size();
        int len[sizeA][sizeB];
        int max =0;
        for(int j = 0; j < sizeB; j++){
            if(A[0] == B[j]){
                len[0][j] = 1;
            }
            else{
                len[0][j] = 0;
            }
        }
        for(int i = 0; i < sizeA; i++){
            if(A[i] == B[0]){
                len[i][0] = 1;
            }
            else{
                len[i][0] = 0;
            }
        }
        for(int i = 1; i < sizeA; i++){
            for(int j = 1; j < sizeB; j++){
                if(A[i] == B[j]){
                    len[i][j] = len[i-1][j-1] +1;
                }
                else{
                    len[i][j] = 0;
                }
                max = len[i][j] > max?len[i][j]:max;
            }
        }
        return max;
    }
};

650. 2 Keys Keyboard

Initially on a notepad only one character ‘A’ is present. You can perform two operations on this notepad for each step:
1.Copy All: You can copy all the characters present on the notepad (partial copy is not allowed).
2.Paste: You can paste the characters which are copied last time.

Given a number n. You have to get exactly n ‘A’ on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n ‘A’.
Example 1:
Input: 3
Output: 3
Explanation:
Intitally, we have one character ‘A’.
In step 1, we use Copy All operation.
In step 2, we use Paste operation to get ‘AA’.
In step 3, we use Paste operation to get ‘AAA’.

Note:
The n will be in the range [1, 1000].

思路:

若要copyall與paste,最後一次copyall時的長度必須是要求長度的因子,所以可將問題轉化成求到最後一次copyall時的長度的最少次數加上剩下copyall與paste的次數(所要求長度/最後一次copyall時的長度)。(若所要求長度有多個因子,求其中最小的步驟次數即可。)
狀態轉移式:
steps[i] = min{steps[j] + i / j|j可爲所有i的因子}

代碼:

class Solution {
public:
    int minSteps(int n) {
        int steps[n+1];
        steps[1] = 0;
        for(int i = 2; i < n + 1; i++){
            steps[i] = i;
        }
        for(int i = 2; i < n + 1; i++){
            for(int j = 2; j < i; j++){
                if(i % j == 0){
                    steps[i] = steps[j] + i / j < steps[i]?steps[j] + i / j : steps[i];
                }
            }
        }
        return steps[n];
    }
};

474. Ones and Zeroes

In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.
For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s.
Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once.
Note:
1.The given numbers of 0s and 1s will both not exceed 100
2.The size of given string array won’t exceed 600.

Example 1:
Input: Array = {“10”, “0001”, “111001”, “1”, “0”}, m = 5, n = 3
Output: 4

Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”

Example 2:
Input: Array = {“10”, “0”, “1”}, m = 1, n = 1
Output: 2

Explanation: You could form “10”, but then you’d have nothing left. Better form “0” and “1”.

思路:

其實就是個二維費用的揹包問題,狀態轉移式爲:
f[i][u][v] = max(f[i-1][u][v], f[i-1][u-numof0][v-numof1] + 1);//f[i][u][v]表示到第i個字符串,若只有u個0與v個1所能形成的最大字符串數。
使用三維數組要注意u-numof0<0或v-numof1<0時直接f[i][u][v] = f[i-1][u][v];//揹包放不下就直接不放
可以直接將原來的三維數組變爲二維數組,轉移式爲:f[u][v] = max(f[u][v], f[u-numof0][v-numof1] + 1);
注意u與v要從大到小計算,因爲要用到的f[u-numof0][v-numof1]必須是上一次(前i-1個字符串)的。

代碼:

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        int size = strs.size();
        int f[m+1][n+1];
        //for(int i = 0; i <= size; i++){
            for(int u = 0; u <= m; u++){
                for(int v = 0; v <= n; v++){
                    f[u][v] = 0;
                }
            }
        //}
        for(int i = 1; i <= size; i++){
            int numof0 = 0;
            int numof1 = 0;
            for(int j = 0; j < strs[i-1].size(); j++){
                if(strs[i-1][j] == '0') numof0++;
                if(strs[i-1][j] == '1') numof1++;
            }
            for(int u = m; u >= numof0; u--){
                for(int v = n; v >= numof1; v--){
                    f[u][v] = max(f[u][v], f[u-numof0][v-numof1] + 1);
                }
            }
        }
        return f[m][n];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章