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 }