Video Reviews

题目链接:http://codeforces.com/gym/101755/problem/K

题目理解: 一家公司想让n个人给他们的产品评论,所以依次去找这n个人,第i个人会评论当且仅当已经有ai个人评论或他确实对这个产品感兴趣,但是这n个人都不对这个产品感兴趣,问这个公司至少要说服几个人对该

      产品该兴趣才能至少收到m个人的评论。假如你要强迫人肯定要强迫最前边的,因为说服一个人对评论数贡献为1​,而提早做贡献可以带来更多的贡献(因为是一个一个地找人,前面的贡献对后面有用)

      对于这种情况,有种强大的方法:二分(二分要强迫的人数)
      二分的好处就是简化复杂度,用假设的已知代替未知,对于求一个最多或最少的问题,通常可以用二分来简单地解决

      像这题,用二分得到确切的强迫次数,那么就可以直接从前往后遍历了

      

 1 /* */
 2 # include <iostream>
 3 # include <stdio.h>
 4 # include <string.h>
 5 # include <algorithm>
 6 # include <cctype>
 7 # include <ctime>
 8 # include <functional>
 9 # include <cmath>
10 # include <bitset>
11 # include <deque>
12 # include <queue>
13 # include <stack>
14 # include <vector>
15 # include <set>
16 # include <map>
17 # include <climits>
18 using namespace std;
19 
20 typedef long long LL;
21 const int maxn=2e5+10;
22 int a[maxn];
23 int n, m;
24 
25 bool check(int k)
26 {
27     int ans=0;///记录评论数
28     int i;
29     for(i=0; i<n; i++ )
30     {
31         if( a[i]<=ans )
32             ans++;
33         else if( k )
34         {
35             ans++;///有强迫名额的话优先强迫
36             k--;
37         }
38         if( ans==m )
39             return true;
40     }
41     return false;
42 }
43 
44 int main()
45 {
46     cin>>n>>m;
47     int i;
48     for(i=0; i<n; i++ )
49     {
50         scanf("%d", &a[i]);
51     }
52 
53     int l=0;
54     int r=m;
55     int ans;
56 
57     while( l<=r )
58     {
59         int mid=(l+r)>>1;
60         if( check(mid) )///如果强迫mid个人可以满足条件,就二分减少强迫的人数
61         {
62              r = mid - 1;
63              ans = mid;
64         }
65         else
66         {
67             l = mid+1;
68         }
69     }
70     printf("%d\n", min(m, ans));///强迫人数大于m, 取m
71     return 0;
72 }
View Code

 

posted @ 2019-08-09 15:44  swsyya  阅读(198)  评论(0编辑  收藏  举报

回到顶部