zoukankan      html  css  js  c++  java
  • Leetcode 1262. 可被三整除的最大和

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

      示例 1:

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

      这道题是第163周竞赛的一道题目,难度中等,边学别人的解题方法,边记录吧!

      

    方案一、不妨设dp[i] 代表 选取的数字累加和 模3 = i 的数字和  

      假定nums[i] % 3 = 1 ,那么,和 前面选取的数字和模 3 = 2 的数相加,就可以模3为 0 ,表达起来就是 dp[0] = max(dp[0], nums[i] + dp[2])依次类推,只要不断更新 dp 数组即可,注意一点,更新的时候要保存上一个状态的值,避免后续更新的时候重复影响。

      

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 int maxSumDivThree(vector<int>& nums) {
     7     int dp[3] = { 0, 0, 0 };
     8     int i;
     9     cout << "┌───────┬───────┬───────┐" << endl;
    10     for (i = 0; i < nums.size(); i++)
    11     {
    12         //依次判断nums[i]
    13         int mod = nums[i] % 3;
    14         int a = dp[(3 + 0 - mod) % 3];//保留上一步的值,避免后续相加影响
    15         int b = dp[(3 + 1 - mod) % 3];
    16         int c = dp[(3 + 2 - mod) % 3];
    17 
    18         if (a||mod == 0) dp[0] = max(dp[0], a + nums[i]);
    19         if (b||mod == 1) dp[1] = max(dp[1], b + nums[i]);
    20         if (c||mod == 2) dp[2] = max(dp[2], c + nums[i]);
    21         cout << "" << dp[0] << "" << dp[1] << "" << dp[2] << "" << endl;
    22         if(i<nums.size()-1)
    23             cout << "├───────┼───────┼───────┤" << endl;
    24         else
    25             cout << "└───────┴───────┴───────┘" << endl;
    26     }
    27 
    28     return dp[0];
    29 }
    30 
    31 vector<int> vc;
    32 int main()
    33 {
    34     int n;
    35     cin >> n;
    36     vc.resize(n);
    37     int i;
    38     for (i = 0; i < n; i++)
    39         cin>>vc[i];
    40     cout << endl;
    41     cout << "能被3整除的最大和为:" <<maxSumDivThree(vc) << endl;
    42     return 0;
    43 }

    理解:(当然这是看的别人的想法,作者https://leetcode-cn.com/u/igamegum/

      先看下运行结果吧,就用上边的实例进行解释:

      

       1、a,b,c是干什么用的?

      a,b,c应该是保留上一步的值,a、b、c的取值如下:

      

       每次均记录了上一步的dp中的值,下一步在计算dp[0]时,dp[0]会发生变化,此时,在计算dp[1]时,用到的dp[0]不再是原始的dp[0],从而造成数据的不一致问题!

      2、if(b || mod == 1)中,为什么还要判断b的值?

      这里的b我理解的是,当它不为0的时候,不过mod值是不是1,我都需要去更新dp[1],因为存在mod是2,需要考虑(2+2)%3=1的情况,同样,mod为0,需要考虑(1+0)%3=1的情况;这里我们去掉试一试,看下结果:

      

      显然,当计算第4层时,数字1%3=1,此时,dp[0]只考虑了mod=0,所以dp[0]没有进行更新,但是数字1+dp[2]也可以构成模3余0的情况,并且和为15,显然比9大!!!

    方案二、国外神代码,没解释,等待理解

     1 class Solution {
     2 public:
     3    int maxSumDivThree(vector<int>& A) {
     4         vector<int> dp = {0, INT_MIN, INT_MIN};
     5         for (int a : A) {
     6             vector<int> dp2 = {0, 0, 0};
     7             for (int i = 0; i < 3; ++i)
     8                 dp2[(i + a) % 3] = max(dp[(i + a) % 3], dp[i] + a);
     9             dp = dp2;
    10         }
    11         return dp[0];
    12     }
    13 };

    理解了之后回来更新~~~

  • 相关阅读:
    linux command line send email
    js的小随笔
    JavaScript的严格模式
    nodejs学习笔记<六>文件处理
    nodejs学习笔记<五>npm使用
    nodejs学习笔记<四>处理请求参数
    nodejs学习笔记<三>关于路由(url)
    nodejs学习笔记<一>安装及环境搭建
    转:HTTP 301 跳转和302跳转的区别
    前端代码新写法——Zen Coding
  • 原文地址:https://www.cnblogs.com/cnyulei/p/11888296.html
Copyright © 2011-2022 走看看