化简一下公式后发现, 问题变成了, 取最少多少数能使其和为1, bitset优化一下背包就好啦。
题解中介绍了一种bfs的方法没, 感觉比较巧妙。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 1000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, k, a[N]; bitset<2010> dp[N]; int main() { scanf("%d%d", &n, &k); for(int i = 1; i <= k; i++) scanf("%d", &a[i]); for(int i = 1; i <= k; i++) { if(a[i] == n) { puts("0"); return 0; } a[i] -= n; } sort(a + 1, a + 1 + k); k = unique(a + 1, a + 1 + k) - a - 1; dp[0][1000] = 1; for(int i = 1; i <= 1000; i++) { for(int j = 1; j <= k; j++) { if(a[j] >= 0) dp[i] |= dp[i - 1] << a[j]; else dp[i] |= dp[i - 1] >> (-a[j]); if(dp[i][1000]) { printf("%d ", i); return 0; } } } puts("-1"); return 0; } /* */