Exams(二分

题意:给你每天要考的科目,和每门科目需要复习多长时间,问最少需要几天才能完成所有的考试。

 

思路:二分答案,然后判断答案是否可行,这边需要进行贪心,即倒着往前推,

比如第i天,那么前面有i-1天是,可供复习的时间是i-1-还有几门科目要考(不包括自己),然后进行判断。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<string>
 7 #include<cmath>
 8 #include<set>
 9 #include<vector>
10 #include<stack>
11 #include<queue>
12 #include<map>
13 using namespace std;
14 #define ll long long
15 #define se second
16 #define fi first
17 const int INF= 0x3f3f3f3f;
18 const int N=1e5+5;
19 
20 int n,m,cnt=0;
21 int a[N],b[N],book[N]={0},loc[N];
22 
23 bool check(int day)
24 {
25     memset(book,0,sizeof(book)); //每次都要清空。。WA点
26     int exam=m;
27     book[0]=1; //漏了。。
28     for(int i=day;i>=1;i--)
29     {
30         if( book[a[i]]==0 )
31         {
32             if( i-1 >= (b[a[i]] + exam-1) ) //可以复习的天数>=当前科目需要复习的天数+前面考试的天数
33             {
34                 //cout<<i-1<<endl;
35                 book[a[i]]=1;
36                 exam--;
37             }
38             else return 0;
39         }
40         if(exam==0) break;
41     }
42     if(exam==0)  return 1;//
43     else return 0;
44 }
45 
46 int main()
47 {
48     int l=0,mid,r;
49     cin>>n>>m;
50     for(int i=1;i<=n;i++){
51         scanf("%d",&a[i]);
52     }
53     for(int i=1;i<=m;i++){
54         scanf("%d",&b[i]);
55         l+= (b[i]+1) ; //复习的天数+考试的一天
56     }
57     r=n;
58     int ans=-1;
59     while(l<=r)
60     {
61         mid=(l+r)>>1;
62         if( check(mid) ){
63             r=mid-1;
64             ans=mid;
65         }
66         else l=mid+1;
67     }
68     if(l>n) cout<<-1;
69     else cout<<l;
70 }
原文地址:https://www.cnblogs.com/thunder-110/p/9304426.html