Factorials and Powers of Two(1500 二进制枚举 dfs)
1 /**\ 2 https://codeforces.com/contest/1646/problem/C 3 题意给出一个数n,选择阶乘数和2次幂数的组合成n,求使用个数最小 4 两种做法: 5 1、dfs 暴力搜索(这道题dfs快点) 6 2、二进制状态压缩枚举 7 \**/ 8 #include <bits/stdc++.h> 9 using namespace std; 10 #define fi first 11 #define se second 12 #define go continue 13 #define int long long 14 #define PII pair<int, int> 15 #define sf(x) scanf("%lld",&x) 16 #define pf(x) printf("%lld\n",x) 17 #define ytz int _; sf(_); while(_--) 18 #define fory(i,a,b) for(int i = a; i <= b; ++i) 19 #define forl(i,a,b) for(int i = a; i >= b; --i) 20 #define debug(a) cout << #a << " = " << a <<endl; 21 22 vector<int> f; 23 inline void init() 24 { 25 for(int i = 1, j = 1; i <= 15; i++) 26 { 27 j = j * i, f.push_back(j); 28 } 29 } 30 int ok; 31 int n; 32 void dfs(int idx, int cnt, int sum) 33 { 34 if(idx == f.size()) 35 { 36 if(sum > n) return; 37 int cot = 0, tmp = n - sum; 38 while(tmp) 39 { 40 if(tmp & 1) cot++; 41 tmp >>= 1; 42 } 43 ok = min(ok, cnt + cot); 44 return; 45 } 46 dfs(idx + 1, cnt + 1, sum + f[idx]); 47 dfs(idx + 1, cnt, sum); 48 } 49 signed main() 50 { 51 init(); 52 ytz 53 { 54 sf(n); 55 ok = 0x3f3f3f3f; 56 dfs(0, 0, 0); 57 pf(ok); 58 } 59 return 0; 60 } 61
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define fi first 4 #define se second 5 #define go continue 6 #define int long long 7 #define PII pair<int, int> 8 #define sf(x) scanf("%lld",&x) 9 #define pf(x) printf("%lld\n",x) 10 #define ytz int _; sf(_); while(_--) 11 #define fory(i,a,b) for(int i = a; i <= b; ++i) 12 #define forl(i,a,b) for(int i = a; i >= b; --i) 13 #define debug(a) cout << #a << " = " << a <<endl; 14 vector<int> f; 15 int n, k; 16 inline void init() 17 { 18 int tmp = 1; 19 for(int i = 1; tmp <= 1e12; i++) 20 { 21 tmp *= i; 22 f.push_back(tmp); 23 } 24 } 25 signed main() 26 { 27 init(); 28 ytz 29 { 30 sf(n); 31 k = 1e18; 32 for(int i = 0; i < (1 << 15); ++i) 33 { 34 int cnt = 0, sum = 0; 35 for(int j = 0; j < 15; ++j) 36 { 37 if(i & (1 << j)) sum += f[j], cnt++; 38 } 39 if(sum > n) go; 40 int tmp = n; 41 tmp -= sum; 42 while(tmp) 43 { 44 if(tmp & 1) cnt++; 45 tmp >>= 1; 46 } 47 k = min(k, cnt); 48 } 49 printf("%lld\n", k); 50 } 51 return 0; 52 }