codeforces 1247C

                传送门: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\n",ans);
34     return 0;
35 }

 

posted @ 2019-10-27 15:32  sj-_-js  阅读(229)  评论(0编辑  收藏  举报