第 109 场 LeetCode 双周赛

A 检查数组是否是好的

第 109 场 LeetCode 双周赛_第1张图片

暴力: 排序后遍历判断

class Solution {
public:
    bool isGood(vector<int> &nums) {
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size() - 1; i++)
            if (nums[i] != i + 1)
                return false;
        return nums.back() == nums.size() - 1;
    }
};

B 将字符串中的元音字母排序

第 109 场 LeetCode 双周赛_第2张图片

模拟: 单独对元音字母排序并对元音字母所在的位置按序赋值

class Solution {
public:
    string sortVowels(string s) {
        set<char> se{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
        vector<char> li;
        for (auto c: s)
            if (se.count(c))
                li.push_back(c);
        sort(li.begin(), li.end());
        int i = 0;
        for (auto &c: s)
            if (se.count(c))
                c = li[i++];
        return s;
    }
};

C 访问数组中的位置使分数最大

第 109 场 LeetCode 双周赛_第3张图片

动态规划: 定义 p i , 0 p_{i,0} pi,0为在 n u m s [ 0 , i ] nums[0,i] nums[0,i]上最后一个访问的元素为偶数的最大得分和, p i , 1 p_{i,1} pi,1为在 n u m s [ 0 , i ] nums[0,i] nums[0,i]上最后一个访问的元素为奇数的最大得分和. p i , j p_{i,j} pi,j的状态只与 p i − 1 , 0 p_{i-1,0} pi1,0 p i − 1 , 1 p_{i-1,1} pi1,1有关.

class Solution {
public:
    typedef long long ll;

    long long maxScore(vector<int> &nums, int x) {
        int n = nums.size();
        ll p[n][2];
        p[0][nums[0] & 1] = nums[0];
        p[0][nums[0] & 1 ^ 1] = INT64_MIN;//无效标志
        ll res = p[0][nums[0] & 1];
        for (int i = 1; i < n; i++) {
            p[i][0] = INT64_MIN;
            p[i][1] = INT64_MIN;
            if (p[i - 1][nums[i] & 1] != INT64_MIN)
                p[i][nums[i] & 1] = max(p[i - 1][nums[i] & 1], p[i - 1][nums[i] & 1] + nums[i]);
            if (p[i - 1][nums[i] & 1 ^ 1]!= INT64_MIN)
                p[i][nums[i] & 1] = max(p[i][nums[i] & 1], p[i - 1][nums[i] & 1 ^ 1] + nums[i] - x);
            p[i][nums[i] & 1 ^ 1] = p[i - 1][nums[i] & 1 ^ 1];
            res = max({res, p[i][0], p[i][1]});
        }
        return res;
    }
};


D 将一个数字表示成幂的和的方案数

第 109 场 LeetCode 双周赛_第4张图片

动态规划: 定义 p v , m x p_{v,mx} pv,mx为将 v v v 表示成一些互不相同且其中最大值为 m x mx mx的正整数的 x 次幂之和的方案数. 有状态转移方程: p v , m x = ∑ k = 0 m x − 1 p v − m x x , k p_{v,mx}=\sum_{k=0} ^{mx-1} p_{v-mx^x, k} pv,mx=k=0mx1pvmxx,k, 实现时可以用前缀和减少计算: s v , i = ∑ k = 0 i p v , k s_{v,i}=\sum_{k=0}^ i p_{v,k} sv,i=k=0ipv,k

typedef long long ll;

ll fpow(ll x, ll n) {//快速幂: x^n
    ll res = 1;
    for (ll cur = 1, e = x; n; e = e * e, n >>= 1)
        if (n & 1)
            res *= e;
    return res;
}

class Solution {
public:
    ll mod = 1e9 + 7;

    int numberOfWays(int n, int x) {
        ll p[n + 1][n + 1];
        ll s[n + 1][n + 1];
        memset(p, 0, sizeof(p));
        memset(s, 0, sizeof(s));
        p[0][0] = 1;
        for (int i = 0; i <= n; i++)
            s[0][i] = 1;
        for (int v = 1; v <= n; v++) {
            for (int mx = 1; mx <= v && v - fpow(mx, x) >= 0; mx++)
                p[v][mx] = s[v - fpow(mx, x)][mx - 1];
            for (int i = 1; i <= n; i++)
                s[v][i] = (s[v][i - 1] + p[v][i]) % mod;
        }
        return (s[n][n] + mod) % mod;
    }
};

你可能感兴趣的:(LeetCode,leetcode,算法,动态规划,职场和发展,C++)