【Leetcode-第260场周赛-数组】2017. 网格游戏(前缀和)

1.问题描述

在这里插入图片描述
在这里插入图片描述

2.解决方案

解法一:错误的动态规划

1.先来一遍dp确定第一个机器人和最大的一条路径,并且反推回去并置零(这算是实现了,但是感觉很傻,后期想一下有没有什么好办法就是关于,记录dp选择序列的)
2.然后grid已经改变了,所以我们要再来一遍dp确定第二个机器人和最大的路径,并且直接输出

class Solution {
public:
    long long gridGame(vector<vector<int>>& grid) {

        int len=grid[0].size();
        vector<vector<long long >> dp(2,vector<long long >(len,-1));
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<len;j++){
                dp[i][j]=grid[i][j];
            }
        }

        //
        for(int i=1;i<len;i++){
            dp[0][i]=dp[0][i]+dp[0][i-1];
        }

        int choose[len];
        dp[1][0]=dp[1][0]+dp[0][0];
        choose[0]=0; //选择了上
        for(int i=1;i<len;i++){
            if(dp[1][i-1]>dp[0][i]){
                dp[1][i]=dp[1][i-1]+dp[1][i];
                choose[i]=1; //选择左
            }
            else{
                dp[1][i]=dp[0][i]+dp[1][i];
                choose[i]=0; //选择上
            }
        }
        //cout<<"第一个机器人最大值:"<<dp[1][len-1]<<endl;
        //到这以及确定了第一个机器人的最大值了

        grid[1][len-1]=0;

        if(choose[len-1]==0){
            for(int i=0;i<len;i++){
                grid[0][i]=0;
            }
        }
        else{
            grid[1][len-2]=0;
            for(int i=len-2;i>=0;i--){
                if(choose[i]==0){
                    for(int j=0;j<=i;j++) grid[0][j]=0;
                    break;
                }
                if(i-1>=0) grid[1][i-1]=0;
            }
        }
        //改变完了



        vector<vector<long long >> dp1(2,vector<long long >(len,-1));
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<len;j++){
                dp1[i][j]=grid[i][j];
            }
        }
        for(int i=1;i<len;i++){
            dp1[0][i]=dp1[0][i]+dp1[0][i-1];
        }
        dp1[1][0]=dp1[1][0]+dp1[0][0];
        for(int i=1;i<len;i++){
            dp1[1][i]=max(dp1[1][i-1],dp1[0][i])+dp1[1][i];
        }
        return dp1[1][len-1];
    }
};

解法二:错误的前缀和

错就错在题目要求使第二个机器人最小化其实其实不等价于 第一个路径和最大了第二个再走就最小化,能举出不少反例,因为很有可能left+right最小了,但是其中的left或者right不是最小和最小可能一个很小一个很大,然后left right才是第二个机器人要走的路啊,所以不是要left+right最小,是要使所有left,right组合中,left right较大的那一个最小了,才是真正的第二个机器人要走的路

思路和解法一差不多,实现很不同
1.维护一个left 和 right,基础left+right的最小值并记录,相当于求了第一个机器人的路径和最大值
2.然后输出

class Solution1 {
public:
    long long gridGame(vector<vector<int>>& grid) {
        //先给一个初始情况就是第一个机器人第0列就开始下到第二行
        long long left=0;
        long long right=0;
        for(int i=1;i<grid[0].size();i++) right+=grid[0][i];

        //遍历第一个机器人下到第二行的列数 1,2...n-1
        //int min=INT_MAX;
        //int min_left=0;
        //int min_right=0;
        long long min=left+right;
        long long min_left=left;
        long long min_right=right;
        for(int i=1;i<grid[0].size();i++){
            right-=grid[0][i];
            left+=grid[1][i-1];
            if(left+right<min){
                min=left+right;
                min_left=left;
                min_right=right;
            }
        }

        //left+right最小的情况下的left和right被记录了
        //其中第二个机器人肯定会选择一个最大的走
        return max(min_right,min_left);

    }
};

解法三:正确的前缀和

在这里插入图片描述

class Solution2 {
public:
    long long gridGame(vector<vector<int>>& grid) {
        //先给一个初始情况就是第一个机器人第0列就开始下到第二行
        long long left=0;
        long long right=0;
        for(int i=1;i<grid[0].size();i++) right+=grid[0][i];

        //遍历第一个机器人下到第二行的列数 1,2...n-1
        long long ans=right;
        for(int i=1;i<grid[0].size();i++){
            right-=grid[0][i];
            left+=grid[1][i-1];
            ans=min(ans,max(left,right));
        }
        return ans;
    }
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值