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 }

 

posted @ 2022-03-07 17:02  std&ice  阅读(76)  评论(0编辑  收藏  举报