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 }