从右到左分别为0-n辆车,每辆车有长度l,起始位置s和速度v,0坐标在左边,不能超车,单车道,问0号车到达0坐标的最短期。html
最短期考虑二分时间,而后按这个时间从左边第一辆车开始依次计算最终位置,最后判断0号车的位置便可。c++
#include <bits/stdc++.h> using namespace std; const int N=1e5+50; const double eps=1e-12; int l[N],s[N],v[N]; int n; bool check(double t){ //判断时间t car可否经过红绿灯 //第一辆车全速 double st=1.0*s[n]-1.0*v[n]*t; double ed=st+l[n]; for(int i=n-1;i>=0;i--){ double tst=1.0*s[i]-1.0*v[i]*t; st=max(ed,tst); ed=st+l[i]; } return st<=0; } int main(void){ // freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ for(int i=0;i<=n;i++){ scanf("%d",&l[i]); } for(int i=0;i<=n;i++){ scanf("%d",&s[i]); } for(int i=0;i<=n;i++){ scanf("%d",&v[i]); } double l=0.0,r=1e9; double ans; while(fabs(l-r)>=eps){ double mid=(l+r)/2; if(check(mid)){ ans=mid; r=mid; }else{ l=mid; } } printf("%.10lf\n",ans); } return 0; }
具体见 http://www.javashuo.com/article/p-sytkfemy-gb.htmlxcode
给一个字符串,以及每一个字符出现次数的限制,找到长度为k的字典序最小的且知足次数限制的子序列。spa
序列自动机预处理出每一个位置后面每一个字符第一次出现的位置和个数,而后每次取出知足条件的最小字符,即取了该字符后,剩下的字符串也要知足最小条件。code
不知足条件的状况多是htm
#include <bits/stdc++.h> using namespace std; const int N=1e5+50; char s[N]; int k; int l[26],r[26],v[26]; int nxt[N][26],cnt[N][26]; int main(void){ // freopen("in.txt","r",stdin); while(~scanf("%s%d",s+1,&k)){ for(int i=0;i<26;i++){ v[i]=0; scanf("%d%d",&l[i],&r[i]); } int n=strlen(s+1); for(int i=0;i<26;i++){ nxt[n][i]=cnt[n][i]=0; } //序列自动机预处理出每一个位置后面每一个字符第一次出现的位置和个数 for(int i=n-1;i>=0;i--){ for(int j=0;j<26;j++){ nxt[i][j]=nxt[i+1][j]; cnt[i][j]=cnt[i+1][j]; } nxt[i][s[i+1]-'a']=i+1; cnt[i][s[i+1]-'a']++; } bool flag=true; string ans=""; int t=0; //每次贪心取最小的,判断剩下后缀可否知足要求 for(int i=0;i<k;i++){ int j=0; //从小到大枚举字符,选择可选的 for(;j<26;j++){ if(cnt[t][j]){ int g=nxt[t][j]; bool ac=true; //尝试选择 v[j]++; //记录后面还须要每种字符的总个数 int ned=0; for(int q=0;q<26;q++){ //选的数量可能会超过l[q] ned+=max(0,l[q]-v[q]); //后面的该字符个数不够下限 || 剩下的可选字符数不够下限 || 该字符已选个数大于上限 if(cnt[g][q]<l[q]-v[q] || k-i-1<l[q]-v[q] || v[q]>r[q]){ ac=false; break; } } //虽然选了这个字符以后,剩余后缀每一个字符数量都能知足限制,但加起来总数不够 if(k-i-1<ned){ ac=false; } v[j]--; if(ac){ ans+=(char)('a'+j); v[j]++; t=g; break; } } } if(j==26){ flag=false; break; } } if(flag){ printf("%s\n",ans.c_str()); }else{ printf("-1\n"); } } return 0; }