题目链接:

https://www.acwing.com/problem/content/1049/

题目大意:

\(n\) 个数字,可以选择其中的若干个,要求它们的和是 \(k\) 的倍数,求最大的和为多少

思路:

因为每选择一个物品的状态可以由上一个状态转移过来,于是想到 \(dp\),就是一个 01 背包,我们将一个物品放入背包中,最后背包的容量为 \(k\) 的倍数,数字 * k 之后很大,但是某个数字对结果有影响的部分只有它 /\(k\) 之后的余数,于是想到 取模
\(dp[i][j]\) 中的 \(i\) 为第 \(i\) 件物品,\(j\) 为对 \(k\) 取模后的结果,写出 01背包。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int w, n, k, dp[N][N];
int main(){
	cin >> n >> k;
	for (int i = 0; i <= n; i++)
		for (int j = 0; j < k; j++)
			dp[i][j] = INT_MIN;
	dp[0][0] = 0;  //不放数的时候结果为 0
	for (int i = 1; i <= n; i++){
		scanf("%d", &w);
		for (int j = 0; j <= k - 1; j++)
			dp[i][j] = max(dp[i - 1][j], dp[i - 1][((j - w) % k + k) % k] + w);
	}
	cout << dp[n][0] << "\n";
	return 0;
}
posted on 2021-11-20 17:03  Hamine  阅读(17)  评论(0编辑  收藏  举报