前言:一开始我想错了,一开始我想的是直接统计每一项模完后的和,我们只要能够取到一半,那么就有解,但是时间复杂度太大了
我们做推导
x + y = s u m x + y = sum x+y=sum
x − y = k ∗ n x - y = k * n x−y=k∗n
那么我们可以得到
2 ∗ x − s u m = k ∗ n 2*x - sum = k*n 2∗x−sum=k∗n
注意:由于取模相当于绕圈圈,所以我们要交替开两个数组记录
题目地址
#include<bits/stdc++.h>
using namespace std;#define int long longconst int N = (int)5e3 + 10;
int n, m;
int a[N];signed main() {cin >> n >> m;int cnt = 0;for (int i = 1; i <= m; i++) {int u; cin >> u;a[i] = u % n;cnt += a[i];}cnt %= n;vector<int> dp(n+10, 0);dp[0] = 1;for (int i = 1; i <= m; i++) {vector<int> temp = dp;for (int j = 0; j <= n; j++) {if (dp[j]) {temp[(j + a[i]) % n] = 1;}}dp = temp;}// x + y = s , x - y = k*n// 2*x - x = k*nint ok = 0;for (int i = 0; i <= n; i++) {if (dp[i] && ((i * 2 - cnt) % n == 0)) {//cout << " i " << i << endl;ok = 1; break;}}if (ok) {cout << "YES";}else cout << "NO";return 0;
}