AcWing 1047.糖果
题目链接:
https://www.acwing.com/problem/content/1049/
题目大意:
n 个数字,可以选择其中的若干个,要求它们的和是 k 的倍数,求最大的和为多少
思路:
因为每选择一个物品的状态可以由上一个状态转移过来,于是想到 dp,就是一个 01背包,我们将一个物品放入背包中,最后背包的容量为 k 的倍数,数字 * k 之后很大,于是想到 取模。
dp[i][j] 中的 i 为第 i 件物品,j 为和 %k 后的结果,写出 01背包。
代码:
#include
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;
}