|
| 1 | +/* |
| 2 | + * Copyright (c) 2021, Christopher Friedt |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: MIT |
| 5 | + */ |
| 6 | + |
| 7 | +// clang-format off |
| 8 | +// name: ones-and-zeros |
| 9 | +// url: https://leetcode.com/problems/ones-and-zeroes |
| 10 | +// difficulty: 2 |
| 11 | +// clang-format on |
| 12 | + |
| 13 | +#include <algorithm> |
| 14 | +#include <vector> |
| 15 | + |
| 16 | +using namespace std; |
| 17 | + |
| 18 | +class Solution { |
| 19 | +public: |
| 20 | + // this is a 2D 1-0 Knapsack problem where |
| 21 | + // each item is either included or not included |
| 22 | + // in the optimal subset and there are 2 different weights |
| 23 | + int findMaxForm(vector<string> &strs, int m, int n) { |
| 24 | + int N = strs.size(); |
| 25 | + |
| 26 | + // create the weight vectors |
| 27 | + w0 = vector<int>(N); |
| 28 | + w1 = vector<int>(N); |
| 29 | + for (int i = 0; i < N; ++i) { |
| 30 | + w0[i] = count(strs[i].begin(), strs[i].end(), '0'); |
| 31 | + w1[i] = strs[i].size() - w0[i]; |
| 32 | + } |
| 33 | + |
| 34 | + // create the values vectors |
| 35 | + // this is mainly for "muscle memory" - with the |
| 36 | + // 0-1 Knapsack problem, elements can still have |
| 37 | + // different weights. |
| 38 | + val = vector<int>(N, 1); |
| 39 | + |
| 40 | + // create a DP area |
| 41 | + dp = vector<vector<vector<int>>>( |
| 42 | + N + 1, vector<vector<int>>(m + 1, vector<int>(n + 1, -1))); |
| 43 | + |
| 44 | + // after we have counted 0's and 1's in strs, it is actually not needed |
| 45 | + // anymore |
| 46 | + return KS(N, m, n); |
| 47 | + } |
| 48 | + |
| 49 | +protected: |
| 50 | + // "weight" in 0's of strs[i] |
| 51 | + vector<int> w0; |
| 52 | + // "weight" in 1's of strs[i] |
| 53 | + vector<int> w1; |
| 54 | + // values of each item |
| 55 | + vector<int> val; |
| 56 | + |
| 57 | + // memoization area for Dynamic Programming solution |
| 58 | + vector<vector<vector<int>>> dp; |
| 59 | + |
| 60 | + int KS(int i, int m, int n) { |
| 61 | + |
| 62 | + // cout << "looking up dp[" << i << "][" << m << "][" << n << "]" << endl; |
| 63 | + auto &result = dp[i][m][n]; |
| 64 | + if (result != -1) { |
| 65 | + return result; |
| 66 | + } |
| 67 | + |
| 68 | + if (i == 0) { |
| 69 | + result = 0; |
| 70 | + return 0; |
| 71 | + } |
| 72 | + |
| 73 | + if (m == 0 && n == 0) { |
| 74 | + result = 0; |
| 75 | + return 0; |
| 76 | + } |
| 77 | + |
| 78 | + if (w0[i - 1] > m || w1[i - 1] > n) { |
| 79 | + result = KS(i - 1, m, n); |
| 80 | + return result; |
| 81 | + } |
| 82 | + |
| 83 | + auto t1 = KS(i - 1, m, n); |
| 84 | + auto t2 = val[i - 1] + KS(i - 1, m - w0[i - 1], n - w1[i - 1]); |
| 85 | + |
| 86 | + result = max(t1, t2); |
| 87 | + return result; |
| 88 | + } |
| 89 | +}; |
0 commit comments