算法分析与设计课程作业第九周#1#2#3

来源:互联网 发布:数据库人员报表查询 编辑:程序博客网 时间:2024/05/16 17:08

算法分析与设计课程作业第九周#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];    }};
原创粉丝点击