題目鏈接:點擊打開鏈接
題意:
給 n 個數,判斷這些數在任意加減的組合下能否被 k 整除;
理解:
看題懵逼;
坐了倆小時,只有看題解;
還好題解能看懂;
說的是這樣的;
首先這些數要通過加減組合起來;
那麼他們的餘數只要等於了 k,就說明能被整除;
於是給定遞推式:前 i 個數的和的餘數是否爲 j;
即:dp[i - 1][j] == 1的情況下,有:dp[i][(j + v[i]) % k] = 1, dp[i][((j - v[i]) % k + k) % k] = 1;
還有更厲害的遞推式:dp[i][j] = dp[i - 1][(j + v[i]) % k] || dp[i - 1][((j - v[i]) % k + k) % k];
初始值爲:dp[0][v[0]] = 1;
即:前 1 數的和的餘數爲 v[0] 的值爲 1;
代碼如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;
#define X first
#define Y second
int aabs(int a) {
return a < 0 ? -a : a;
}
int dp[10010][110];
int main() {
int n = 1, k;
while (cin >> n >> k) {
vector<int> v(n);
for (int i = 0; i < n; ++i) {
cin >> v[i];
v[i] = aabs(v[i]) % k;
}
dp[0][v[0]] = 1;
for (int i = 1; i < n; ++i) {
for (int j = k - 1; j >= 0; --j) {
if (dp[i - 1][j]) {
dp[i][(j + v[i]) % k] = 1;
dp[i][((j - v[i]) % k + k) % k] = 1;
}
}
}
if (dp[n - 1][0] == 1) {
cout << "Divisible" << endl;
}
else {
cout << "Not divisible" << endl;
}
}
return 0;
}