zoukankan      html  css  js  c++  java
  • [蓝桥杯2018初赛]倍数问题

    题目描述

    众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。
    但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。
    现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数
    使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。

    输入

    第一行包括 2 个正整数 n, K。
    第二行 n 个正整数,代表给定的 n 个数。
    1 <= n <= 10^5, 1 <= K <= 10^3,给定的 n 个数均不超过 10^8。

    输出

    输出一行一个整数代表所求的和。

    样例输入
    4 3
    1 2 3 4
    样例输出
    9

    分析:首先看这个题,从n个数中选三个数,且三个数相加的和是k的倍数,且满足倍数中最大。
    那么这一看就是背包空间3,选数满足特殊要求,的01背包吧。

    现在分析怎么才能构成k的倍数, 假设我们 k=3,要选一个数4,要让它构成3的倍数,然后要选另一个数,
    那么另一个数要让它余数为零,则要找余数为(0 – x%k + k)%k的数,则推出两个数相加要求余数不变,则满足(当前余数 - x%k + k)%k的数。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <iostream>
      6 using namespace std;
      7 
      8 const int N = 1010;
      9 
     10 int n, m;
     11 vector<int> a[N];
     12 int f[4][N];//4代表当前选的数,N代表余数 
     13 
     14 int main()
     15 {
     16     scanf("%d%d", &n, &m);
     17 
     18     for (int i = 0; i < n; i ++ )
     19     {
     20         int x;
     21         scanf("%d", &x);
     22         a[x % m].push_back(x);//将数按余数分组 
     23     }
     24 
     25     memset(f, -9999, sizeof f);
     26     f[0][0] = 0;
     27 
     28     for (int i = 0; i < m; i ++ )//枚举余数背包 
     29     {
     30         sort(a[i].rbegin(), a[i].rend());//从大到小排序 
     31 
     32         for (int u = 0; u < 3 && a[i].size() > u; u ++ )//每个分组最多选三个最大的 
     33         {
     34             int x = a[i][u];
     35 
     36             for (int j = 3; j >= 1; j -- )
     37                 for (int k = 0; k < m; k ++ ){//枚举余数 
     38 
     39                     f[j][k] = max(f[j][k], f[j - 1][(k - x%m + m) % m] + x);
     40                     //f[j - 1][(k - x%m + m) % m] + x保证相加后的余数还为k 
     41                 }
     42         }
     43     }
     44 
     45     printf("%d\n", f[3][0]);//输出我们要的余数为零的数 
     46 
     47     return 0;
     48 }
     49 

    追求吾之所爱
  • 相关阅读:
    应用部署架构演进【转载】
    TiDB 学习笔记一(运维管理)
    c++ strcmp函数
    C++ sort()函数
    C++ 遍历set的三种方式
    nvcc fatal : '--ptxas-options=-v': expected a number
    PAT A1039 Vector的使用
    C++ set
    C++ int与string互转换
    C++%f和%lf的区别
  • 原文地址:https://www.cnblogs.com/rstz/p/14391051.html
Copyright © 2011-2022 走看看