标签:eof noip git cst include ams 直接 char oid
思路:二分+贪心
提交次数:10次以上
错因:刚开始以为二分(边界,$+1or-1$)写错了,调了半天,后来才发现是$ck()$写错了。开始只判了最后是否小于零,而应该中间一旦小于零就$return\space false$
题解:
二分天数(单调性显然)。
$ck(int x)$: 首先$x$天内必须包含所有科目;然后贪心的考每一科的最后一次试(倒着扫一遍);维护一个剩余天数$cnt$,遇到空闲时间或不是最后本科目的一次考试就$++$,否则$-=$本科考试所需的复习天数;一旦$cnt<0$,直接$return\space false$;最后$return\space cnt>=0$。
代码:
#include<cstdio> #include<iostream> #include<cstring> using namespace std; //你弱,有什么资格休息 #define ull unsigned long long #define ll long long #define R register ll #define pause (for(R i=1;i<=10000000000;++i)) #define In freopen("NOIPAK++.in","r",stdin) #define Out freopen("out.out","w",stdout) namespace Fread { static char B[1<<15],*S=B,*D=B; #ifndef JACK #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++) #endif inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix; if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline bool isempty(const char& ch) {return (ch<=36||ch>=127);} inline void gs(char* s) { register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar())); } } using Fread::g; using Fread::gs; namespace Luitaryi { const int N=1e+5+10; int n,m,ans=-1,cnt; int a[N],w[N]; bool vis[N],flg[N]; inline bool ck(int x) { R ret=0,tmp=m; memset(vis,0,sizeof(vis)); memset(flg,0,sizeof(flg)); for(R i=x;i>=1&&tmp;--i) if(a[i]&&!vis[a[i]]) vis[a[i]]=true,flg[i]=true,--tmp; if(tmp!=0) return false; for(R i=1;i<=x;++i) { if(a[i]!=0&&flg[i]) ret-=w[a[i]]; else ++ret; if(ret<0) return false; } return ret>=0; } inline void main() { n=g(),m=g(); for(R i=1;i<=n;++i) a[i]=g(); for(R i=1;i<=m;++i) w[i]=g(); R l=m,r=n+1; while(l<r) { R md=l+r>>1; if(ck(md)) r=md; else l=md+1; } printf("%d\n",l==n+1?-1:l); } } signed main() { Luitaryi::main(); return 0; }
2019.07.14
标签:eof noip git cst include ams 直接 char oid
原文地址:https://www.cnblogs.com/Jackpei/p/11186523.html