第229场周赛

前两道都很简单暴力就能做。

5685. 交替合并字符串

class Solution {
public:
    string mergeAlternately(string word1, string word2) {
        string res;
        int s1=word1.size();
        int s2=word2.size();
        int i=0;
        while(i<s1&&i<s2){
            res+=word1[i];
            res+=word2[i];
            i++;
        }
        for(int j=i;j<s1;j++)res+=word1[j];
        for(int j=i;j<s2;j++)res+=word2[j];
        return res;
    }
};

5686. 移动所有球到每个盒子所需的最小操作数

class Solution {
public:
    vector<int> minOperations(string boxes) {
        int n=boxes.size();
        vector<int>res(n);
        for(int i=0;i<n;i++){
            int cnt=0;
            for(int j=0;j<n;j++){
                if(boxes[j]=='1')cnt+=abs(j-i);
            }
            res[i]=cnt;
        }
        return res;
    }
};

5687. 执行乘法运算的最大分数


给你nums数组和M数组,遍历M数组然后每次M[i]选一个nums数组左右端点其中一个相乘贡献答案(选到的就把它删去)。问选m个之后的答案的贡献最大多少。


首先这是一个区间dp问题。不过看到大佬用的记忆化搜索写的更简单。

记忆化搜索

状态f[l][r]表示l选几个r选几个。那么res=f[0][0]。让它往下搜m层即可。这里需要注意的是n的范围1e6。而m范围1e3。相比定义状态我们不能这样定义f[l][r]表示区间[l,r]的贡献答案,那么答案就变成了f[0][n-1]。状态就变成了这样,这样数组存不下那么大的二维空间

int lvalue=dfs(cur+1,l+1,r,n,m,nums,M)+M[cur]*nums[l];
 int rvalue=dfs(cur+1,l,r+1,n,m,nums,M)+M[cur]*nums[r];

因此定义第一种状态。

const int N=1e3+50;
int f[N][N];
class Solution {
public:
    int dfs(int cur,int l,int r,int n,int m,vector<int>& nums, vector<int>& M)
    {
        if(cur>=m) return 0;
        if(f[l][r]!=-1)return f[l][r];
        int lvalue=dfs(cur+1,l+1,r,n,m,nums,M)+M[cur]*nums[l];
        int rvalue=dfs(cur+1,l,r+1,n,m,nums,M)+M[cur]*nums[n-1-r];
        f[l][r]=max(lvalue,rvalue);
        return f[l][r];
    }
    int maximumScore(vector<int>& nums, vector<int>& M) {
        memset(f,-1,sizeof f);
        int n=nums.size(),m=M.size();
        return dfs(0,0,0,n,m,nums,M);
    }
};

5688. 由子序列构造的最长回文串的长度


给你两个串,求两个串的非空子序列合并得到一个字符串。并且该字符串是回文串,且长度最大。


首先要知道怎么求一个字符串的最长回文子序列。力扣题库就有。其次我们可以把两个字符串合并在一起。然后就变成了求合并后的最长回文子序列的长度。但是还有一个限制,要求是两个串非空。这个你只要满足i在第一个区间j在第二个区间即可。


const int N=2e3+5;
class Solution {
public:
    int f[N][N];
    int longestPalindrome(string word1, string word2) {
        string s=word1+word2;
        int len1=word1.size(),len2=word2.size(),n=s.size(),res=0;
        for(int i=n-1;i>=0;i--){
            f[i][i]=1;
            for(int j=i+1;j<n;j++){
                if(s[i]==s[j]){
                    f[i][j]=f[i+1][j-1]+2;
                    if(i<len1&&j>=len1)res=max(res,f[i][j]);
                }else f[i][j]=max(f[i+1][j],f[i][j-1]);
            }
        }
        //cout<<f[0][n-1];
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_43566782/article/details/113921896