为自己能想出怎么做而高兴
为自己想半天写出来之后各种bug而蛋疼
题目链接 ←题意戳链接
分析一下之后发现,最优解显然只有四种情况:(证明略→_→)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<iomanip> #include<vector> #include<set> #include<map> #include<queue> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define rep(i,k,n) for(int i=(k);i<=(n);i++) #define rep0(i,n) for(int i=0;i<(n);i++) #define red(i,k,n) for(int i=(k);i>=(n);i--) #define sqr(x) ((x)*(x)) #define clr(x,y) memset((x),(y),sizeof(x)) #define pb push_back #define mod 1000000007 const int maxn=500010; char c[maxn]; int f[2][maxn]; int g[2][maxn]; int d[2]={1,-1}; int eend[2]; bool vis[maxn]; int n,a,b,T; int getf(int dir,int l,int r,int tim) { int dd=d[dir]; int mid; while((r-l)*dd>0) { if(dd==1)mid=l+r+1>>1; else mid=l+r>>1; if(g[dir][mid]<=tim)l=mid; else r=mid-dd; } return dir?n-l:l; } int main() { scanf("%d%d%d%d",&n,&a,&b,&T); scanf("%s",c); clr(f,0x3f); int tmp=1; if(c[0]=='w')tmp+=b; if(tmp>T) { puts("0"); return 0; } if(n==1) { puts("1"); return 0; } int ans=1; f[0][0]=f[1][0]=tmp; g[0][0]=g[1][0]=0; eend[0]=n-1;eend[1]=1; rep(dir,0,1)for(int i=(d[dir]+n)%n,cnt=1;cnt<n;i=(i+d[dir])%n,cnt++) { int dd=d[dir]; int last=(i-dd+n)%n; f[dir][i]=f[dir][last]+a+1; if(c[i]=='w')f[dir][i]+=b; g[dir][i]=f[dir][i]-tmp; if(f[dir][i]>T) { eend[dir]=i; break; } } rep(dir,0,1)for(int i=(d[dir]+n)%n,cnt=1;cnt<n;i=(i+d[dir])%n,cnt++) { int dd=d[dir]; if(f[dir][i]>T)break; //nt last=(i-dd+n)%n; int next=(i+dd+n)%n; ans=max(ans,cnt+1); tmp=f[dir][i]+cnt*a; if(cnt<n-1 && g[dir^1][(-dd+n)%n]+tmp<=T) { int r; if(eend[dir^1]==next)r=next; else if((eend[dir^1]-next)*dd>0)r=eend[dir^1]; else r=next; ans=max(ans,cnt+1+getf(dir^1,(-dd+n)%n,r,T-tmp)); } } printf("%d\n",ans); return 0; }