待补
引子
题解
大模拟,注意细节
代码1
#includeusing namespace std; int n,m;char a[1005][1005];bool vst[1005][1005]; void solve(int na,int nb) { int i=na,j=nb,now=0; while(1){ j++;if(a[na][j]=='+')break; } while(1){ i++;if(a[i][nb]=='+')break; } for(int k=na+1;k){ for(int l=nb+1;l if(a[k][l]>='0'&&a[k][l]<='9')now=now*10+a[k][l]-'0'; if(now)break; } for(int k=i;k>=na;k--){ if(j<=m&&a[k][j+1]=='-'){ int ni=k,nj=j+1;vst[ni][nj]=1; while(1){ while(1){ if((a[ni][nj+1]=='-'||a[ni][nj+1]=='+')&&!vst[ni][nj+1])nj++; else nj--;vst[ni][nj]=1; if(a[ni][nj]=='+')break; } while(1){ ni++;vst[ni][nj]=1; if(a[ni][nj]=='+'||a[ni][nj]=='-')break; } if(a[ni][nj]=='-')break; } while(a[ni][nj]!='+')nj--;solve(ni,nj); } else if(nb&&a[k][nb-1]=='-'){ int ni=k,nj=nb-1; vst[ni][nj]=1; while(1){ while(1){ if((a[ni][nj+1]=='-'||a[ni][nj+1]=='+')&&!vst[ni][nj+1])nj++; else nj--;vst[ni][nj]=1; if(a[ni][nj]=='+')break; } while(1){ ni++;vst[ni][nj]=1; if(a[ni][nj]=='+'||a[ni][nj]=='-')break; } if(a[ni][nj]=='-')break; } while(a[ni][nj]!='+')nj--; solve(ni,nj); } } printf("%d\n",now); } int main() { bool fir=0; int sta,stb; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ char c=getchar(); while(c!='+'&&c!='|'&&c!='-'&&c!='.'&&(c>'9'||c<'0'))c=getchar(); a[i][j]=c; if(a[i][j]=='+'&&!fir)sta=i,stb=j,fir=1; } solve(sta,stb); return 0; }
代码2
#includeusing namespace std; #define ll long long #define A 1111 char ch[A][A]; ll n,m,top=0; ll h[A][A],stax[A],stay[A],low[A],len[A],sta[A]; ll chuanx,chuany; bool vis[A][A]; struct node { ll hang,id; friend bool operator < (const node &a,const node &b){ return a.hang<b.hang; } }; priority_queue high[A]; const ll nowx[5]={0,1,-1,0,0}; const ll nowy[5]={0,0,0,1,-1}; //1右0左2下 void pre(ll x,ll y,ll fx){ if(h[x][y]){ // printf("x=%lld y=%lld h=%lld fx=%lld\n",x,y,h[x][y],fx); chuanx=x,chuany=y; return ; } if(ch[x][y]=='+'){ if(fx==0||fx==1){ pre(x+1,y,2); } if(fx==2){ if(ch[x][y+1]=='-') pre(x,y+1,1); if(ch[x][y-1]=='-') pre(x,y-1,0); } } else{ if(fx==1&&y+1<=m) pre(x,y+1,1); if(fx==0&&y-1>=1) pre(x,y-1,0); if(fx==2&&x+1<=n) pre(x+1,y,2); } } void dfs(ll num){ while(!high[num].empty()){ ll x=high[num].top().id; // printf("hang=%lld\n",high[num].top().hang); high[num].pop(); dfs(x); } low[++low[0]]=num; } void del(ll x,ll y,ll num){ top=1; // printf("num=%lld\n",num); stax[top]=x,stay[top]=y; while(top){ ll x=stax[top],y=stay[top]; h[x][y]=num; top--; for(ll i=1;i<=4;i++){ ll x2=x+nowx[i],y2=y+nowy[i]; h[x2][y2]=num; // printf("x2=%lld y2=%lld\n",x2,y2); if((ch[x2][y2]=='.'||isdigit(ch[x2][y2]))&&!vis[x2][y2]){ top++; stax[top]=x2,stay[top]=y2; vis[x2][y2]=1; } } } // printf("*********************%lld\n",h[14][61]); } void bfs(){ for(ll i=1;i<=n;i++) for(ll j=1;j<=m;j++){ if(isdigit(ch[i][j])){ // printf("ch[%lld][%lld]=%d\n",i,j,ch[i][j]-'0'); ll x=ch[i][j]-'0'; for(ll w=j+1;w<=m;w++){ if(isdigit(ch[i][w])) x=x*10+ch[i][w]-'0'; else break; } // printf("x1=%lld x2=%lld x3=%lld\n",x,x2,x3); if(!vis[i][j])del(i,j,x); } } /* for(ll i=1;i<=n;i++,puts("")) for(ll j=1;j<=m;j++){ printf("%lld",h[i][j]); } */ for(ll i=1;i<=n;i++) for(ll j=1;j<=m;j++){ if(ch[i][j]=='|'){ if(ch[i][j+1]=='-'){ pre(i,j+1,1); node no; // printf("i=%lld j=%lld h=%lld chan=%lld %lld h=%lld\n",i,j,h[i][j],chuanx,chuany,h[chuanx][chuany]); no.hang=i,no.id=h[chuanx][chuany]; high[h[i][j]].push(no); } if(ch[i][j-1]=='-'){ pre(i,j-1,0); node no; // printf("i=%lld j=%lld h=%lld chan=%lld %lld h=%lld\n",i,j,h[i][j],chuanx,chuany,h[chuanx][chuany]); no.hang=i,no.id=h[chuanx][chuany]; high[h[i][j]].push(no); } } } dfs(1); for(ll i=1;i<=low[0];i++){ printf("%lld\n",low[i]); } } int main(){ // freopen("wos.txt","w",stdout); scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++){ scanf("%s",ch[i]+1); } bfs(); }
可爱宝贝精灵
题解
一个不错的dfs题(还能练习剪枝)
一个不错的dp题
思考dp数组含义
首先我们知道我们到一个有小精灵地方就必须抓住它(显然)而不是来回逛几圈再次经过它再抓
然后我们只要从一个方向走就必须抓住至少一只小精灵,转向之后也至少抓住一只精灵,(否则你走这一段就是没用的)
$i,j$分别表示当前最左到$i$最右到$j$时的最大值
设$f[i][j]$肯定不行时间难以确认,多一维表示时间$f[t][i][j]$也难以确定,然而你在左面还是右面依然难以确定
那么再加一维$f[t][i][j][2]$中$[1]$表示在右面,$[0]$表示在左面
转移很好转移,不像昨天那个傻逼t2式子
类似离散化一下
假如当前l,你可以走到r或者l-1
假如当前r,你可以走到l或者r+1
用式子表示就是
从$r$走到$l+1$再走到$l$
从$l$走到$r-1$再走到$r$
$f[i][l][r][0]=max(f[max(i-dis(l,l+1),0)][l+1][r][0],f[max(i-dis(l,r),0)][l+1][r][1])+Val;$
$f[i][l][r][1]=max(f[max(i-dis(r-1,r),0)][l][r-1][1],f[max(i-dis(l,r),0)][l][r-1][0])+Val;$
注意一下初始化!
#includeusing namespace std; #define ll long long #define py printf("tys is sb\n") #define A 2010 ll f[A][118][118][2]; struct pocky{ ll pla,val,tim; friend bool operator < (const pocky &a, const pocky &b){ return a.pla<b.pla; } }texas[A]; ll dis(ll l,ll r){ return abs(texas[r].pla-texas[l].pla); } ll n,k,m,mx,mid,ans; void debuger(ll x){ for(ll i=1;i<=m;i++,puts("")) for(ll j=i+1;j<=m;j++){ printf("f[%lld][%lld][%lld]=%lld %lld\n ",x,i,j,f[x][i][j][1],f[x][i][j][0]); } } int main(){ scanf("%lld%lld%lld",&n,&k,&m); for(ll i=1;i<=m;i++){ scanf("%lld%lld%lld",&texas[i].pla,&texas[i].val,&texas[i].tim); mx=max(mx,texas[i].tim); } memset(f,-0x3f,sizeof(f)); m++; texas[m].pla=k, texas[m].val=0, texas[m].tim=mx; sort(texas+1,texas+m+1); for(ll i=1;i<=m;i++){ if(texas[i].pla==k&&texas[i].val==0){ mid=i; break; } } f[0][mid][mid][0]=0; f[0][mid][mid][1]=0; // printf("mid=%lld \n",texas[mid].pla); for(ll i=mid-1;i>=1;i--){ ll tim=texas[mid].pla-texas[i].pla; // printf("tim=%lld i=%lld mid=%lld \n",tim,i,mid); f[tim][i][mid][0]=f[dis(mid,i+1)][i+1][mid][0]+((tim 0); ans=max(ans,f[tim][i][mid][0]); } for(ll i=mid+1;i<=m;i++){ ll tim=texas[i].pla-texas[mid].pla; f[tim][mid][i][1]=f[dis(mid,i-1)][mid][i-1][1]+((tim 0); ans=max(ans,f[tim][mid][i][1]); } // printf("ans=%lld\n",ans); for(ll i=1;i<=mx;i++) for(ll l=1;l<=mid-1;l++) for(ll r=mid+1;r<=m;r++){ f[i][l][r][0]=max(f[max(i-dis(l,l+1),0ll)][l+1][r][0],f[max(i-dis(l,r),0ll)][l+1][r][1])+((i 0); f[i][l][r][1]=max(f[max(i-dis(r-1,r),0ll)][l][r-1][1],f[max(i-dis(l,r),0ll)][l][r-1][0])+((i 0); ans=max(ans,max(f[i][l][r][0],f[i][l][r][1])); // printf(" f[%lld][%lld][%lld][0]=%lld [%lld][%lld][%lld][1]=%lld\n",i,l,r,f[i][l][r][0],i,l,r,f[i][l][r][1]); } printf("%lld\n",ans); }
相互在归的鹅妈妈