传送门:https://codeforces.com/contest/1247/problem/C
题意::给你一个 n 和 p,有这样的一种二级制 “p-binary” ( 2^x+p , x非负 ); 要你用最少数量的 “p-binary”之和表示 n;无法构成输出-1;
数据大小: 1<=n<=1e9;-100<=p<=100;
分析::
因为 1e9<=2^31,所以我们只需枚举 i ( 1<=i<=31 )即可,根据题意推出变形后的等式 n-i*p == Σ (2^k) ;
假设 组成 n 的数出现重复了,重复数必然可以用一个更大的来代替,所以枚举的 i 指的是最小数量(当拆成更小的数时其数量必然增加,一定符合要求),这样也最小化了答案 只要保证 n-i*p 转化成 2^k之和 所需的最小数量<=i 即可;
1 #include<bits/stdc++.h> 2 #define ull unsigned long long 3 #define ll long long 4 const int inf=1e9+7; 5 const int maxn=1e6+5; 6 using namespace std; 7 8 bool check(ll x,ll y) 9 { 10 if(x<=0) 11 return 0; 12 ll ans=x,t=0; 13 while(ans)//求最小的组合数量 14 { 15 if(ans&1) 16 t++; 17 ans/=2; 18 } 19 return y>=t&&x>=y;// x>=y 因为2^k是大于等于1,x至少要大于构成种数y(不然构成不了) 20 } 21 int main() 22 { 23 ll n,p,ans=-1; 24 scanf("%lld%lld",&n,&p); 25 for(int i=1;i<=31;i++) 26 { 27 if(check(n-i*p,i)) 28 { 29 ans=i; 30 break; 31 } 32 } 33 printf("%lld ",ans); 34 return 0; 35 }