给你一个整数数组 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

方法一:贪心做法
如果一开始数组中所有的数字和是3的倍数的话,那么就直接输出就可以了。
如果一开始数组中所有的数字和取余3等于1的话,有两种情况:
①减去一个取余3为1的数字
②减去两个取余3为2的数字
这两种情况取最优
如果一开始数组中所有的数字和取余3等于2的话,有两种情况:
①减去一个取余3为2的数字
②减去两个取余3为1的数字
这两种情况取最优

class Solution {
public:int maxSumDivThree(vector<int>& nums) {int N = nums.size();vector<int> div1,div2,div3;\int sum = 0;for(int i=0;i<N;++i){if(nums[i]%3==0)div3.push_back(nums[i]);else if(nums[i]%3==1)div1.push_back(nums[i]);else if(nums[i]%3==2)div2.push_back(nums[i]);sum += nums[i];}if(sum%3==0)return sum;else if(sum%3==1){if(div2.size()<2 && div1.empty())return 0;else if(div2.size()<2){sort(div1.begin(),div1.end());return sum-div1[0];}else if(div1.empty()){sort(div2.begin(),div2.end());return sum-div2[0]-div2[1];}else{sort(div1.begin(),div1.end());sort(div2.begin(),div2.end());return max(sum-div2[0]-div2[1],sum-div1[0]);}}else if(sum%3==2){if(div1.size()<2 && div2.empty())return 0;else if(div1.size()<2){sort(div2.begin(),div2.end());return sum-div2[0];}else if(div2.empty()){sort(div1.begin(),div1.end());return sum-div1[0]-div1[1];}else{sort(div1.begin(),div1.end());sort(div2.begin(),div2.end());return max(sum-div1[0]-div1[1],sum-div2[0]);}}return sum;}
};

方法二:动态规划

分析这个样例可以知道,这是一道01背包的问题。每个数只能选一次。
不过,样例里面还有1,8被选进去。这是因为 1%3 = 1, 8%3 = 2. 也就是说,对于被3整除的最大和,还需要考虑被1和2整除的最大和,并且每个数只能使用一次。
因此,状态就出来了:
dp[i][j]表示前 i 个数中模 3 余 j 的最大和。
一开始dp[0][1]和dp[0][2]都初始化为INT_MIN.
下面上dp打表的图。

状态转移方程:
dp[i][j] = max(dp[i-1][j], dp[i-1][*] + nums[i-1]); ( * 根据情况而定)
比如 t%3 == 2
对于dp[i][0],有前两种状态可以递推得到:

  1. dp[i-1][1] + t
  2. dp[i-1][0]

从这两种状态中取最大值,就是前 i 个数中%3==0的最大和。
在上述式子中,我们也需要保证dp[i-1][1]是最大的,因此我们要写3个dp,并且要分类讨论。
下面上代码:

class Solution {
public:int maxSumDivThree(vector<int>& nums) {int n = nums.size();int dp[n+2][3];memset(dp,0,sizeof(dp));dp[0][0] = 0; dp[0][1] = INT_MIN; dp[0][2] = INT_MIN;for(int i = 1;i <= n;i++){int t = nums[i-1]%3;if(t == 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]);}else if(t == 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]);}else if(t == 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]);}}for(int i = 1;i <= n;i++){for(int j = 0;j <= 2;j++){cout<<dp[i][j]<<" ";}cout<<endl;}return dp[n][0];}
};

可被三整除的最大和—leetcode1262相关推荐

  1. LeetCode1262 可被三整除的最大和(动态规划)

    给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和. 示例 1: 输入:nums = [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 ...

  2. 1262. 可被三整除的最大和(贪心||动态规划)

    给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和. 示例 1: 输入:nums = [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 ...

  3. LeetCode 1262. 可被三整除的最大和(DP)

    1. 题目 给你一个整数数组 nums,请你找出并返回能被三整除的元素最大和. 示例 1: 输入:nums = [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 ...

  4. leetcode算法题--可被三整除的最大和

    原题链接:https://leetcode-cn.com/problems/greatest-sum-divisible-by-three/ 动态规划 dp[0]存储余数为0的最大和 dp[1]存储余 ...

  5. 2455. 可被三整除的偶数的平均值

    2455. 可被三整除的偶数的平均值 给你一个由正整数组成的整数数组 nums ,返回其中可被 3 整除的所有偶数的平均值. 注意:n 个元素的平均值等于 n 个元素 求和 再除以 n ,结果 向下取 ...

  6. 接上个例子1-100之间能被三整除的流程步骤详解。

    上个例子为1-100之间所有能被3整除的数字之和,今天这个笔记将详细记录这个代码的流程. 假设将if语句开始到printf 用{}括起来,看看这段代码是怎样进行运算的. int main(void) ...

  7. 网易2018实习生笔试题 被三整除

    时间限制:1秒 空间限制:32768K 问题描述: 小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011.... 并且小Q对于能否被3整除这个性质很 ...

  8. if语句matlab求被三整除的数,matlab能被3或4整除语句

    在1-200的自然数中,能被2整除,或能被3整除,或能被5整除的数有多少个 上面犯了一个错误算被5整除的数应该÷5,他÷4了可以被2整除的数:200÷2=100个可以被3整除的数:200÷3≈66个( ...

  9. C ++ 函数模板求三个数的最大和

    #include <iostream> using namespace std; //声明函数模板 template<typename T> T max(T a, T b, T ...

最新文章

  1. window.opener 的用法
  2. bootstrap 一排5个_9个非常实用的CSS图标库
  3. Alfred+AppleScript实现快速复制当前文件夹路径
  4. java中outer的使用
  5. SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)
  6. Java Spring源代码研究之Bean的名称是大小写相关吗?
  7. 二叉树:HDU1754
  8. 血型遗传关系c语言编程,根据血型遗传关系,编程实现:○1.输入
  9. 稳定币兑换器Orbits发布路线图,包括发行治理代币ORB等
  10. fcn+caffe+siftflow实验记录
  11. 爬虫python下载视频_利用python爬虫通过m3u8文件下载ts视频
  12. mongodb 非 admin 库 认证登陆失败 原因(百度好多都 是渣)db.addUser() 请走开。
  13. ASCII码字符对照表 阿斯克码表
  14. java中常用的算法--URL
  15. 茆诗松等《高等数理统计(第二版)》例 1.28 的错误及改正
  16. 如何修改开机背光亮度
  17. Pubwin服务端重装(安装)教程
  18. 光环:研发云搭建及人才梯队建设——姚冬
  19. I don't know what to say 事件的 NPM 包中奖名单,有你在用的吗?
  20. easypoi 语法_高中英语语法:高中英语必修1选修8全八册知识点总结

热门文章

  1. 2013豆瓣校园招聘研发类笔试题
  2. c/s项目记住账号密码功能
  3. Oracle触发器简单使用记录
  4. 《训练指南》——8.5
  5. 在最美好的年华里,不要辜负最美的自己
  6. Git_git的诞生
  7. Recordset.State 属性
  8. [网络安全提高班] 一〇一.网络攻防溯源普及和医疗数据安全总结
  9. 【数据结构与算法】之深入解析“修剪二叉搜索树”的求解思路与算法示例
  10. 【数据结构与算法】之“接雨水”的算法求解