第 111 场双周赛 - 力扣(LeetCode)

第 111 场双周赛 - 力扣(LeetCode)

2824. 统计和小于目标的下标对数目 - 力扣(LeetCode)

枚举即可

class Solution {
public:
    int countPairs(vector<int>& nums, int target) {

        int n = nums.size();
        int ans = 0;
        for(int i = 0;i + 1< n;i ++){
            for(int j = i + 1; j < n;j ++){
                if(nums[i] + nums[j] < target)
                    ans ++;
            }
        }
        return ans;
    }
};

2825. 循环增长使字符串子序列等于另一个字符串 - 力扣(LeetCode)

双指针跑一遍即可

class Solution {
public:
    bool canMakeSubsequence(string str1, string str2) {
        int cnt = 0;
        for (int i = 0; i < str1.size(); i ++) {
            if (str1[i] == str2[cnt]) {
                cnt ++;
            } else if (str1[i] + 1 == str2[cnt] || str1[i] == 'z' && str2[cnt] == 'a') {
                cnt ++;
            }
        }
        if (cnt == str2.size()) {
            return true;
        }
        return false;
    }
};

2826. 将三个组排序 - 力扣(LeetCode)(状态机dp)

哈哈赛时写了个暴力shit代码qwq,算了能过就行

shit代码
class Solution {
public:
    int minimumOperations(vector& nums) {
        int n = nums.size();
        int ans = n;
        if(nums == vector(n,1) || nums == vector(n,2) || nums == vector(n,3))
            return 0;
        for(int i = 0;i + 1 < n;i ++){
            if(nums[i] > nums[i + 1]) break;
            if(i == n - 2)
                return 0;
        }
        int numi = 0,numj = 0,numk = 0;
        for(int i = 0;i < n;i ++){
            numi += (nums[i] != 1);
        }
        for(int j = 0;j < n;j ++){
            numj += (nums[j] != 2);
        }
        for(int k = 0;k < n;k ++){
            numk += (nums[k] != 3);
        }
        ans = min({ans, numk,numi,numj});
        numk = 0,numi = 0, numj = 0;
        for(int j = 0;j < n;j ++){
            numj += (nums[j] != 2);
            numk = 0;
            for(int k = j + 1;k < n;k ++){
                numk += (nums[k] != 3);
            }
            ans = min(ans, numj + numk);
        }
        numi = 0,numj = 0,numk = 0;
        for(int i = 0;i < n;i ++){
            numi += (nums[i] != 1);
            numj = 0,numk = 0;
            for(int j = i + 1;j < n;j ++){
                numj += (nums[j] != 2);
                numk = 0;
                for(int k = j + 1;k < n;k ++){
                    numk += (nums[k] != 3);
                }
                ans = min(ans, numi + numj + numk);
            }
            ans = min(ans, numi +numj +numk);
            numk = 0;
            for(int j= i + 1;j< n;j++){
                numk += (nums[j] != 3);
            }
            ans = min(ans, numi + numk);
        }
        return ans ;
    }
};

正解是\(dp\)啦,

\(dp[i][j]\)表示到第\(i\)个数为止,将第\(i\)个数改成\(j\)后的最小步数

class Solution {
public:
    int minimumOperations(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> dp(n,vector<int>(4,0));
        dp[0][1] = nums[0]!=1;
        dp[0][2] = nums[0]!=2;
        dp[0][3] = nums[0]!=3;
        for(int i=1;i<n;i++){
            dp[i][1] = dp[i-1][1]+(nums[i]!=1);
            dp[i][2] = min(dp[i-1][1]+(nums[i]!=2),dp[i-1][2]+(nums[i]!=2));
            dp[i][3] = min(dp[i-1][1],min(dp[i-1][2],dp[i-1][3]))+(nums[i]!=3);
        }
        return min(dp[n-1][1],min(dp[n-1][2],dp[n-1][3]));
    }
};

可以省略第一维,即每次找最小的进行转移

class Solution {
public:
    int minimumOperations(vector<int>& nums) {
        int f[4]{0};
        for(auto num : nums)
            for(int i = 3;i ; i--)
                f[i] = *min_element(f + 1, f + i + 1) + (i != num);

        return *min_element(f + 1, f + 4);
    }
};

2827. 范围中美丽整数的数目 - 力扣(LeetCode)(数位dp)

后面补qwq

posted @ 2023-08-22 01:15  Ke_scholar  阅读(13)  评论(0编辑  收藏  举报