9.2 OPPO笔试 后端(B卷)

前两题打卡

第一题注意”最多操作1次“,可以不操作,否则只能过70%

第三题动态规划,dp[i][j]表示为以str[i]为最后一个”oppo“右端点的情况下,有j个”oppo“字串

分两种情况,如果以str[i-3]为第j-1个字串的右端点,则最后一个字串是”ppo“;其余情况最后一个字串是”oppo“

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        in.nextLine();
        String str = in.nextLine();
        if (str.length() < 4 + (k-1)*3){
            System.out.println(-1);
            return;
        }
        int[][] dp = new int[str.length() + 1][k + 1];
        //避免计算,直接存最小值
        int[][] minn = new int[str.length() + 1][k + 1];
        for (int i = 0; i < dp.length; i++) {
            Arrays.fill(dp[i],0x7ffffff0);
            Arrays.fill(minn[i],0x7ffffff0);
        }
        for (int i = 0; i <= str.length(); i++) {
            dp[i][0] = 0;
            minn[i][0] = 0;
        }
        for (int i = 1; i <= str.length(); i++) {
            for (int j = 1; j <=k ; j++) {
                int targetLen = 4 + (j-1)*3;
                if (i < targetLen){
                    dp[i][j] = 0x7ffffff0;
                    continue;
                }
                //长度满足
                if (j == 1){
                    //o p  p   o
                    //    i-1  i
                    int opNum = 0;
                    if (str.charAt(i-1) != 'o') opNum++;
                    if (str.charAt(i-2) != 'p') opNum++;
                    if (str.charAt(i-3) != 'p') opNum++;
                    if (str.charAt(i-4) != 'o') opNum++;
                    dp[i][j] = dp[i-4][j-1] + opNum;
                    minn[i][j] = Math.min(minn[i-1][j],dp[i][j]);
                } else {
                    // p p o 情况
                    int opNum = 0;
                    if (str.charAt(i-1) != 'o') opNum++;
                    if (str.charAt(i-2) != 'p') opNum++;
                    if (str.charAt(i-3) != 'p') opNum++;
                    dp[i][j] = dp[i-3][j-1] + opNum;
                    if (str.charAt(i-4) != 'o') opNum++;
                    dp[i][j] = Math.min(minn[i-4][j-1] + + opNum,dp[i][j]);
//                    for (int l = 4; l <= i-4 ; l++) {
//                        dp[i][j] = Math.min(dp[l][j-1] + opNum,dp[i][j]);
//                    }
                    minn[i][j] = Math.min(minn[i-1][j],dp[i][j]);
                }
            }
        }
        int res = 0x7fffffff;
        for (int i = 4 + (k-1)*3; i <= str.length() ; i++) {
            res = Math.min(res,dp[i][k]);
        }
        System.out.println(res);
    }

`

#oppo#
全部评论
这个第三题好像不对吧 我用第三个测试用例好像就不行
点赞 回复 分享
发布于 2023-09-16 22:01 陕西
第一题是呀?我就只过了60多
点赞 回复 分享
发布于 2023-09-03 12:56 湖北

相关推荐

03-16 02:27
中山大学 C++
#笔试# A题意:给你n个数,求满足下列条件的数的个数:将这个数变为它的相反数后,所有数的和属于[0,t]n1e5思路:模拟即可B题意:给你n个非负整数,对于每个数,求将这个数删掉以后剩下所有数的mex(最小未出现的非负整数)n2e5思路:考场上脑子不清醒写了个权值线段树上二分。。出来后才想到更简单的做法。*&nbsp;考虑对原数组排序后去重形成的新数组,我们可以把新数组划分成两部分:以0为首项,公差为1的等差数列为一部分,剩下的东西为第二部分。*&nbsp;第二部分的数删掉对mex没有影响。*&nbsp;第一部分的数对mex的影响则要看这个数在原数组里出现了几次,如果只出现了一次会更改mex,否则mex不变。C题意:给你一个n位的十进制数(这个数不含前导0),其中有些位被挖空了。你可以在这些位上填数字,满足最后得到的n位十进制数是3的倍数。求填数字的方案数模1e9+7思路:*注意到&nbsp;十进制数模3的余数&nbsp;=&nbsp;它的各个数位和模3的余数&nbsp;。*可以考虑动态规划:设dp[i][j]表示填到第i位,前i位的数位和模3为j的方案数。*只要把状态设出来了转移方程应该都写。一些实现上的细节:*看到好几个过了样例但爆零的了。如果不是思路有误很大可能是取模出了问题。*对每个运算都需要进行取模*(针对c或c++,其他语言不知道)在进行乘法运算时,如果你的变量是int类型的,需要在运算时转换成long&nbsp;long(因为3e9已经爆int了)#牛客AI配图神器#
投递OPPO等公司8个岗位 笔试
点赞 评论 收藏
分享
评论
5
8
分享

创作者周榜

更多
牛客网
牛客企业服务