参考了这篇文章写的,感觉讲的挺清晰的。我自己有些细节还是没处理好,比如是i-1还是i这种。dp的题目除了要解决状态转移方程,初始化是最头疼的,比如这题dp[0][0]=0, 后面2个都是INT_MIN就很不容易想到。
cpp实现:
/*
* @lc app=leetcode.cn id=1262 lang=cpp
*
* [1262] 可被三整除的最大和
*/
#include<iostream>
#include<vector>
using namespace std;
// @lc code=start
class Solution {
public:
int maxSumDivThree(vector<int>& nums) {
// 状态转移方程:dp[i][*] = max(dp[i-1][*],dp[i-1][**]+nums[i])
int numslen = nums.size();
// 开数组
int dp[100000][3];
// dp[i][0]:当前最大和模3余0
// dp数组初始化
dp[0][0] = 0, dp[0][1] = INT_MIN, dp[0][2] = INT_MIN;
for (int i=1; i<numslen+1; i++){
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]);
}
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]);
}
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[numslen][0];
}
};
// @lc code=end
int main(){
//test
return 0;
}