2018年蓝桥杯C++A组第9题倍数问题

倍数问题

众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。

但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。

现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。

数据保证一定有解。

输入格式
第一行包括 2 个正整数 n, K。

第二行 n 个正整数,代表给定的 n 个数。

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

数据范围
1≤n≤105,
1≤K≤103,
给定的 n 个数均不超过 108
输入样例:
4 3
1 2 3 4
输出样例:
9

这显然是一道背包问题,即从一些数中选择一些数的问题,下面是闫氏dp分析法:

在这里插入图片描述
既然已经分析完了,那么代码就好写了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N=1010,M=3*N;
const int INF=2e9;
vector<int> a[N];
int f[4][N];
int g[4][N];
int n,m;

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		a[x%m].push_back(x);
	} 
	memset(f,-0x3f,sizeof f);//一个都不选的话,余数为其它值的情况不存在,因此总和赋值为负无穷,因此初始化为负无穷,这样后面max操作会自动把它过滤掉
	f[0][0]=0;//一个不选的话,余数为0,总和也为0
	for(int op=0;op<m;op++)
	{
		sort(a[op].begin(),a[op].end());
		reverse(a[op].begin(),a[op].end());
		for(int i=0;i<3&&i<a[op].size();i++)
		{
			int w=a[op][i];
			for(int j=3;j>=1;j--)
			{
				for(int k=0;k<m;k++)
				f[j][k]=max(f[j][k],f[j-1][(k-w%m+m)%m]+w);
			}
		}
	}
	cout<<f[3][0];
	return 0;
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值