LeetCode 1262. 可被三整除的最大和--动态规划

  1. 可被三整除的最大和

给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和。

示例 1:

输入:nums = [3,6,5,1,8]
输出:18
解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。

示例 2:

输入:nums = [4]
输出:0
解释:4 不能被 3 整除,所以无法选出数字,返回 0。

示例 3:

输入:nums = [1,2,3,4,4]
输出:12
解释:选出数字 1, 3, 4 以及 4,它们的和是 12(可被 3 整除的最大和)。

提示:

1 <= nums.length <= 4 * 10^4
1 <= nums[i] <= 10^4

题解:

点击这里查看同类题目:LeetCode算法题目合集

比较有趣的题目,看数组长度可以猜到应该用的解题思路,先看数据吧,因为题目要求被3整除,余数我们从左到右依次遍历累计求和然后对3取模,有3种结果:0、1、2。于是我们用数组dp[maxn][3]分别表示累计和到数字nums[i]时,余数为0的最大值为dp[i][0],也就是恰好被3整除为我们的目标答案,同理余数为1的最大值为dp[i][1],余数为2的最大值为dp[i][2],为什么储存这个结果呢?因为当遍历到数字nums[i]时,可能(dp[i-1][0]+nums[i])%3不一定为0,但是!可能(dp[i-1][1]+nums[i])%3或者(dp[i-1][2]+nums[i])%3就为0,于是我们需要进行更新,先比较原来的
dp[i][j]=max(dp[i][j],dp[i-1][j]);
然后做处理
int res=(dp[i-1][j]+nums[i])%3;//res表示新的余数
dp[i][res]=max(dp[i][res],dp[i-1][j]+nums[i]);//nuns[i]取还是不取做比较

就得到答案了

AC代码

class Solution {
public:
    int dp[40010][3];
    int maxSumDivThree(vector<int>& nums) {
        memset(dp,0,sizeof(dp));
        dp[0][nums[0]%3]=nums[0];//初始化
        for(int i=1;i<nums.size();i++)
        {
            for(int j=0;j<3;j++)
            {
                dp[i][j]=max(dp[i][j],dp[i-1][j]);//先和上一级做比较
                int res=(dp[i-1][j]+nums[i])%3;//res表示新的余数
                dp[i][res]=max(dp[i][res],dp[i-1][j]+nums[i]);//nuns[i]取还是不取做比较
            }
        }
        return dp[nums.size()-1][0];
    }
};

LeetCode 1262. 可被三整除的最大和--动态规划_第1张图片

你可能感兴趣的:(LeetCode,动态规划,算法,leetcode,动态规划)