给你一个整数数组 nums,请你找出并返回能被三整除的元素 最大和。
思路:
最开始考虑的是用01背包问题,对每个元素动态取舍,最后找到最大值。但感觉用数组一直存,可能会爆炸,因为和可能会很大。
因此选择动态递归的方式,找到取前i个和取前i+1个元素的关系。
会发现:假如现在对于前i个元素,可以被三除余j,则对于第i个元素x,如果取了,那么要在前i-1个元素中,找到被三除余j-x。如果不取,就是在前i-1个元素中找到被三除余j。因此可以得到关系式,然后用这个关系求解即可。
然后要考虑的是边界条件,就是当i<0的情况,此时对于前-1个元素,无疑只能找除3余0的,余1和余2均是不存在,因此设定余1余2都是负无穷,这样就不会取到了。
class Solution {
public:
int maxSumDivThree(vector<int>& nums) {
const int n=nums.size();
int memo[n][3];
memset(memo,-1,sizeof(memo));
auto dfs=[&](auto &&dfs,int i,int j)->int{
if(i<0)return j?INT_MIN:0;
int &res=memo[i][j];
if(res!=-1)return res;
return res=max(dfs(dfs,i-1,j),dfs(dfs,i-1,(dfs,j+nums[i])%3)+nums[i]);
};
return dfs(dfs,n-1,0);
}
};