#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#defineendl'\n'voidsolve(){int n, a, b;
cin >> n >> a >> b;int res =1e8;for(int i =0; i <= n / a; i ++){for(int j =0; i * a + j * b <= n; j ++){
res =min(res, n - i * a - j * b);}}
cout << res << endl;}signedmain(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);int T;// cin >> T;
T =1;while(T --)solve();return0;}
发现对于每个数字i, 满足 i + 2^x <= n,则有 x = log2(n - i), 再 + 1即为每个数的最大贡献,也就是 x + 1,例如对于数字1,它的贡献是 log2(5-1) + 1 = 3,因为向下取整的原因 + 1,同理对于数字2,log2(5-2) + 1 = 2
得到每个数字i的贡献后,将k总值减去对应的数字的贡献值,并将其放到最后
例如 5 5, 可得 3 4 5 2 1, 因为1贡献了3个二元组,2贡献了2个二元组
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#defineendl'\n'constint N =1e6+10;int flag1[N], flag2[N];int lg[N];voidsolve(){int n, k;
cin >> n >> k;for(int i =2; i <= n; i ++) lg[i]= lg[i >>1]+1;for(int i =1; i <= n; i ++) flag1[i]=1;for(int i =1; i < n; i ++){int cha = n - i;if(lg[cha]+1<= k){
flag1[i]=0;
flag2[i]=1;
k -= lg[cha]+1;}if(k ==0)break;}if(k >0){
cout <<-1<< endl;return;}for(int i =1; i <= n; i ++)if(flag1[i]) cout << i <<" ";for(int i = n; i >=1; i --)if(flag2[i]) cout << i <<" ";}signedmain(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);int T;// cin >> T;
T =1;while(T --)solve();return0;}