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;
}
};