A 找出数组中的 K-or 值
模拟
class Solution {
public:int findKOr(vector<int> &nums, int k) {vector<int> cnt(32);for (auto x: nums)for (int i = 0; i < 32; i++)if (x >> i & 1)cnt[i]++;int res = 0;for (int i = 0; i < 32; i++)if (cnt[i] >= k)res |= 1 << i;return res;}
};
B 数组的最小相等和
分类讨论:将两个数组中的 0 0 0 看作 1 1 1 求数组替换完后的最小数组和,若两个数组的最小数组和相等返回 0 0 0 ,否则只有最小数组和较小的一个数组存在 0 0 0 有解。
class Solution {
public:using ll = long long;long long minSum(vector<int> &nums1, vector<int> &nums2) {ll s1 = 0, s2 = 0;//两个数组的最小数组和bool have1 = false, have2 = false;//两个数组是否含有0for (auto x: nums1) {if (x)s1 += x;else {have1 = true;s1 += 1;}}for (auto x: nums2) {if (x)s2 += x;else {have2 = true;s2 += 1;}}if (s1 > s2) {swap(s1, s2);swap(have1, have2);}if (s1 == s2)return s1;return have1 ? s2 : -1;}
};
C 使数组变美的最小增量运算数
动态规划:设 p [ i ] p[i] p[i] 为将 n u m s [ 0 , i ] nums[0,i] nums[0,i] 变为美丽数组且满足 n u m s [ i ] ≥ k nums[i]\ge k nums[i]≥k 的最小递增运算数,有状态转移方程: p [ i ] = { m a x { k − n u m s [ i ] , 0 } i < 3 m i n { p [ i − 1 ] , p [ i − 2 ] , p [ i − 3 ] } + m a x { k − n u m s [ i ] , 0 } , i ≥ 3 p[i]=\left\{\begin{matrix} max\{k-nums[i],0\} & i<3 \\ min\{p[i-1],p[i-2],p[i-3] \}+max\{k-nums[i],0\} & ,i\ge 3 \end{matrix}\right. p[i]={max{k−nums[i],0}min{p[i−1],p[i−2],p[i−3]}+max{k−nums[i],0}i<3,i≥3
class Solution {
public:using ll = long long;long long minIncrementOperations(vector<int> &nums, int k) {int n = nums.size();ll p[n];for (int i = 0; i < 3; i++)p[i] = max(k - nums[i], 0);for (int i = 3; i < n; i++) {p[i] = min({p[i - 1], p[i - 2], p[i - 3]}) + max(k - nums[i], 0);}return min({p[n - 1], p[n - 2], p[n - 3]});}
};
D 收集所有金币可获得的最大积分
记忆化搜索:设 p [ c u r ] [ c n t ] p[cur][cnt] p[cur][cnt] 为以 c u r cur cur 为根的子树在之前已经使用了 c n t cnt cnt 次第二种方法的情况下可获得的最大积分,有状态转移方程: p [ c u r ] [ c n t ] = m a x { ⌊ c o i n s [ c u r ] 2 c n t ⌋ − k + ∑ j ∈ s o n ( c u r ) p [ j ] [ c n t ] ⌊ c o i n s [ c u r ] 2 c n t + 1 ⌋ + ∑ j ∈ s o n ( c u r ) p [ j ] [ c n t + 1 ] p[cur][cnt]=max\left\{\begin{matrix} \left \lfloor \frac {coins[cur]} {2^{cnt}} \right \rfloor-k + \sum_{j\in son(cur)}p[j][cnt] \\ \left \lfloor \frac {coins[cur]} {2^{cnt+1}} \right \rfloor + \sum_{j\in son(cur)}p[j][cnt+1] \end{matrix}\right. p[cur][cnt]=max⎩ ⎨ ⎧⌊2cntcoins[cur]⌋−k+∑j∈son(cur)p[j][cnt]⌊2cnt+1coins[cur]⌋+∑j∈son(cur)p[j][cnt+1]
class Solution {
public:int maximumPoints(vector<vector<int>> &edges, vector<int> &coins, int k) {int n = coins.size();vector<int> e[n];for (auto &ei: edges) {e[ei[0]].push_back(ei[1]);e[ei[1]].push_back(ei[0]);}int M = 16, inf = INT32_MIN;int p[n][M];for (int i = 0; i < n; i++)for (int j = 0; j < M; j++)p[i][j] = inf;//初始化标志function<int(int, int, int)> dfs = [&](int cur, int cnt, int par) {//记忆化搜索if (p[cur][cnt] != inf)return p[cur][cnt];if (cnt == M - 1)//子树所有数已经为都0,接下来全用第二种方法return p[cur][cnt] = 0;int r1 = (coins[cur] >> cnt) - k, r2 = coins[cur] >> (cnt + 1);for (auto j: e[cur]) {if (j == par)continue;r1 += dfs(j, cnt, cur);r2 += dfs(j, cnt + 1, cur);}return p[cur][cnt] = max(r1, r2);};return dfs(0, 0, -1);}
};