贴一下常规做法,不过会$TLE+MLE$。不过具有$dp$的普适性。
1.定义状态
$dp(i,j,k)$ 前$i$个物品选$j$个总和$\%k$的最大值。
2.初始化( 极其重要 )
前$i$个数选$0$个模$k$的最大值都为$0$,其他都应该是负无穷,因为选$0$个数总和$%k$只能为$0$。
而没选物品的总和为$0\ \%k$不可能为其他值。
3.状态转移
对第i个物品选与不选进行状态转移:
$dp(i,j,k)=max(dp(i-1,j,k),dp(i-1,j-1,(k-a[i])\%k))$
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
int n, K, a[N];
int main(void){
cin >> n >> K;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
vector<vector<vector<int>>> dp(n + 1, vector<vector<int>> (4, vector<int> (K, -2e9)));
for (int i = 0; i <= n; i++) dp[i][0][0] = 0;
for (int i = 1; i <= n; i++){
for (int j = 1; j <= 3; j++){
for (int k = 0; k < K; k++){
dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - 1][((k - a[i]) % K + K) % K] + a[i]);
}
}
// printf("%d %d %d\n", dp[i][1][0], dp[i][2][0], dp[i][3][0]);
}
cout << dp[n][3][0];
return 0;
}
为什么初始化为-2e9
这为什么不会超时呢?时间复杂度不是 3 * 10 ^ 8 吗
现在过不了了呀
一开始就说了会TLE+MLE
这个好理解多了
不会超时吗
vector[HTML_REMOVED]>> dp(n + 1, vector[HTML_REMOVED]> (4, vector[HTML_REMOVED] (K, -2e9)));
这个是干什么的啊
初始化三维vector
太感谢了!!
%%谢谢大佬
所以这题要贪心优化,只需取前3大数。即第一维n将为k
是的,不过我写的目的是为了给那些只需要知道一般普适性做法的人看的