leetcode第1262题 可被三整除的最大和
题目
可被三整除的最大和
给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和。
思路
每个数只有选和不选两种状态,那么根据什么转移呢,因根据当前数模3之后3的余数来进行转移。
- dp[i][0]=到i为止被三整除的最大和
- dp[i][1]=到i为止除三余1的最大和
- dp[i][2]=到i为止除三余2的最大和
- 当nums[i-1]%3==0时,加入当前的数字不会对除以三的结果造成影响
dp[i][0]=max(dp[i-1][0],dp[i-1][0]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][1]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][2]+nums[i-1]);
- 当nums[i-1]%3==1时,那加入nums[i]之后,本来余0的就会余1,本来余1的余2,本来余2的余0
else if(nums[i-1]%3==1)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][2]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+nums[i-1]);
}
- 同理,如果当前数字除以3余2,那加入nums[i]之后,本来余0的就会余2,本来余1的就会余0,本来余2的就会余1
//如果当前数字除以3余2,那加入nums[i]之后,本来余0的就会余2,本来余1的就会余0,本来余2的就会余1
else if(nums[i-1]%3==2)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][2]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][0]+nums[i-1]);
}
最后返回dp[n][0]
代码
class Solution {
public:
//dp[i][0]=到i为止被三整除的最大和
//dp[i][1]=到i为止除三余1的最大和
//dp[i][2]=到i为止除三余2的最大和
int maxSumDivThree(vector<int>& nums) {
int n=nums.size();
vector<vector<int>>dp(n+1,vector<int>(3));
dp[0][0] = 0, dp[0][1] = -0x3f3f3f3f, dp[0][2] = -0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
//如果当前数字可以被3整除,那加入nums[i]之后就不会影响除3的结果
if(nums[i-1]%3==0)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][0]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][1]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][2]+nums[i-1]);
}
//如果当前数字除以3余1,那加入nums[i]之后,本来余0的就会余1,本来余1的余2,本来余2的余0
else if(nums[i-1]%3==1)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][2]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+nums[i-1]);
}
//如果当前数字除以3余2,那加入nums[i]之后,本来余0的就会余2,本来余1的就会余0,本来余2的就会余1
else if(nums[i-1]%3==2)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+nums[i-1]);
dp[i][1]=max(dp[i-1][1],dp[i-1][2]+nums[i-1]);
dp[i][2]=max(dp[i-1][2],dp[i-1][0]+nums[i-1]);
}
}
return dp[n][0];
}
};
简化版本(来自leetcode题解)
class Solution {
public:
int maxSumDivThree(vector<int>& nums) {
int n = nums.size(), sum = 0;
vector<vector<int>> f(n + 1, vector<int>(3));
f[0][0] = 0, f[0][1] = -0x3f3f3f3f, f[0][2] = -0x3f3f3f3f;
for(int i=1;i<=n;i++) {
int x = nums[i - 1] % 3;
f[i][0] = max(f[i-1][0], f[i-1][(3 - x)%3] + nums[i-1]);
f[i][1] = max(f[i-1][1], f[i-1][(3-x+1)%3] + nums[i-1]);
f[i][2] = max(f[i-1][2], f[i-1][(3-x+2)%3] + nums[i-1]);
}
return f[n][0];
}
};
作者:mt19937
链接:https://leetcode-cn.com/problems/greatest-sum-divisible-by-three/solution/xian-xing-dp-by-mt19937-etfv/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。