Time Limit:1s Memory Limit:64MByte
Submissions:148Solved:85
Coco just learned a math operation call mod.Now,there is an integer aa and nn integers b1,…,bnb1,…,bn. After selecting some numbers from b1,…,bnb1,…,bn in any order, say c1,…,crc1,…,cr, Coco want to make sure that amodc1modc2mod…modcr=0amodc1modc2mod…modcr=0 (i.e., aa will become the remainder divided by cici each time, and at the end, Coco want aa to become 00). Please determine the minimum value of rr. If the goal cannot be achieved, print −1−1 instead.
先对数组排序,从大到小,因为mod大的数,不会对MOD小的数有影响,但是因为余数比MOD小的数更大,所以因子数只会更多。机会只会更多,就像样例一样,先MOD 7,再MOD 2.
所以用dfs枚举每一个数,MOD和不MOD都选一次。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 1e6 + 20; int a[maxn]; int n, ans; int val; void dfs(int selct, int re, int cur) { if (selct >= ans) return; if (re == 0) { ans = min(ans, selct); return; } if (cur > n) return; dfs(selct + 1, re % a[cur], cur + 1); dfs(selct, re, cur + 1); } void work() { scanf("%d%d", &n, &val); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); sort(a + 1, a + 1 + n, greater<int>()); ans = inf; dfs(0, val, 1); if (ans == inf) printf("-1 "); else printf("%d ", ans); } int main() { freopen("data.txt","r",stdin); int t; scanf("%d", &t); while (t--) work(); return 0; }
状压:dp[state]表示现在MOD了那位数字,然后枚举的时候,也是优先MOD了大的数字,再转移去小的数字。不允许先MOD小的再转移去MOD大的,就是2--3这条路径是不行的,因为2--3就是先MOD2,再MOD1得到,但是可以先MOD1,再MOD2得到。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #define MY "H:/CodeBlocks/project/CompareTwoFile/DataMy.txt", "w", stdout #define ANS "H:/CodeBlocks/project/CompareTwoFile/DataAns.txt", "w", stdout #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 2e6 + 20; int dp[maxn]; int a[maxn]; int get(int val) { int ans = 0; while (val) { val &= (val - 1); ans++; } return ans; } int cnt[maxn]; void init() { int end = (1 << 20) - 1; for (int i = 0; i <= end; ++i) { cnt[i] = get(i); } return; } void work() { int ans = inf; int n, val; scanf("%d%d", &n, &val); for (int i = 0; i < n; ++i) { scanf("%d", &a[i]); } sort(a, a + n, greater<int>()); memset(dp, 0x3f, sizeof dp); for (int i = 0; i < n; ++i) { dp[1 << i] = val % a[i]; if (dp[1 << i] == 0) ans = 1; } int end = (1 << n) - 1; for (int j = 1; j <= end; ++j) { if (cnt[j] >= ans) continue; for (int i = 0; i < n; ++i) { if (((1 << i) & j) != 0) continue; int state = j | (1 << i); if (cnt[state] >= ans) continue; if (dp[state] != inf) continue; dp[state] = dp[j] % a[i]; if (dp[state] == 0) ans = cnt[state]; } } if (ans == inf) printf("-1 "); else printf("%d ", ans); } int main() { init(); int t; scanf("%d", &t); while (t--) work(); return 0; }