如果没有arr数组,先看累加的到1-range范围上的所有数,最少需要几个数。

  1. 缺少1,在有了1之后,就可以得到1-1范围上的所有数;需要添加新鲜的数字1,得到更新的[1,1]
  2. [1,1]缺少2,需要添加新鲜的数字2,得到更新后的[1,3] =[1,2,1+2],实际的数字(1,2)
  3. [1,3]缺少4,需要添加新鲜的数字4, 得到更新后的[1,7]=[1,2,1+2,4,1+4,2+4,1+2+4],注意这里不能得到8因为实际的数字只有(1,2,4)三个
  4. [1,7]缺少8,需要添加新鲜的数字8,(实际数字1,2,4,8)
    得到更新后的[1,15]=[1,2,1+2,4,1+4,2+4,1+2+4,8,1+8,2+8,1+2+8,4+8,1+4+8,2+4+8,1+2+4+8]
    接下来缺少8,有了8之后就可以得到1-15范围内所有的
    观察总结可以得到:如果已经搞定1-cur范围上的所有数,下一个缺的数就是cur+1,有了cur+1之后,就可以搞定1-2*cur+1范围内的所有数。添加(cur+1)这个新的数字才能对原来的范围有所改变
    当有一个有序的正数数组arr时,在从左到右遍历arr时进行如下操作:
  • 设置变量cur,表示已经搞定了1~cur范围上的数。初始时令cur=0,表示没有范围确定。
  • 遍历到arr[0],如果arr[0]大于1,那么就要添加数字,添加的就是cur+1,即添加1,并令统计需要数字+1。
  • 直到arr[i]<=cur+1时,这个时候的的范围就变成了cur+arr[i]。
  • 可能到arr[arr.length-1]后都没有满足,代表需要在末尾继续添加。
  • 一直到cur>=range时,返回此时统计的值。
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
      priority_queue<int,vector<int>,greater<int> > q;
      int n,k;
      cin>>n>>k;
      for(int i=0;i<n;i++){
          int temp=0;
          cin>>temp;
          q.push(temp);
      }
      int cur=0;
      int res=0;
      while(cur<k){
          if(!q.empty()){
              int x=q.top();
              if(x<=cur+1){
                  cur+=x;
                  q.pop();
              }
              else {
                  res++;
                  cur+=cur+1;
              }
          }
          else{
              res++;
              cur+=cur+1;
          }
      }
      cout<<res<<endl;
    }