1 条题解
-
1
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define hash deep_dark_fantasy #define inf 1e9 using namespace std; inline int read(){ int re=0,flag=1;char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') flag=-1; ch=getchar(); } while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar(); return re*flag; } int n,m,x[150][150],cur,pre,ex,ey; int st[2][300010];ll ans[2][300010],re; int tot[2],bit[20],state[300010],st_tot,hash=300000; struct edge{ int to,next; }a[300010]; void insert(int sta,ll val){//往哈希表里插入一个状态,顺便更新答案 int p=sta%hash,i; for(i=state[p];i;i=a[i].next){ if(st[cur][a[i].to]==sta){ ans[cur][a[i].to]=max(ans[cur][a[i].to],val);return; } } tot[cur]++; a[++st_tot].to=tot[cur]; a[st_tot].next=state[p]; state[p]=st_tot;st[cur][tot[cur]]=sta;ans[cur][tot[cur]]=val; } void dp(){ int i,j,k,l,now,down,right;ll val;re=-inf; cur=0;tot[cur]=1;ans[cur][1]=0;st[cur][1]=0; for(i=1;i<=n;i++){ for(j=1;j<=tot[cur];j++) st[cur][j]<<=2; for(j=1;j<=m;j++){ pre=cur;cur^=1;tot[cur]=0;st_tot=0;memset(state,0,sizeof(state)); for(k=1;k<=tot[pre];k++){ now=st[pre][k];val=ans[pre][k]; right=(now>>bit[j-1])%4;down=(now>>bit[j])%4; if(!down&&!right){//新建联通分量,加一个下插头一个右插头 insert(now,val); if(j!=m) insert(now+(1<<bit[j-1])+((1<<bit[j])<<1),val+x[i][j]); } if(down&&!right){//延续下插头 insert(now-down*(1<<bit[j])+down*(1<<bit[j-1]),val+x[i][j]); if(j!=m)insert(now,val+x[i][j]); } if(right&&!down){//延续右插头 insert(now,val+x[i][j]); if(j!=m) insert(now+right*(1<<bit[j])-right*(1<<bit[j-1]),val+x[i][j]); } if(right==1&&down==1){//合并两个左括号 int cnt=1; for(l=j+1;l<=m;l++){ if((now>>bit[l])%4==1) cnt++; if((now>>bit[l])%4==2) cnt--; if(!cnt){ insert(now-(1<<bit[l])-(1<<bit[j])-(1<<bit[j-1]),val+x[i][j]); break; } } } if(right==2&&down==2){//合并两个右括号 int cnt=1; for(l=j-2;l>=0;l--){ if((now>>bit[l])%4==1) cnt--; if((now>>bit[l])%4==2) cnt++; if(!cnt){ insert(now+(1<<bit[l])-((1<<bit[j])<<1)-((1<<bit[j-1])<<1),val+x[i][j]); break; } } } if(right==2&&down==1){//合并)( insert(now-((1<<bit[j-1])<<1)-(1<<bit[j]),val+x[i][j]); } if(right==1&&down==2){//合并(),统计答案 if((now==(1<<bit[j-1])+((1<<bit[j])<<1))&&(val+x[i][j]>re)){ re=val+x[i][j]; } } } } } } int main(){ int i,j; n=read();m=read(); for(i=1;i<=10;i++) bit[i]=(i<<1); for(i=1;i<=n;i++) for(j=1;j<=m;j++) x[i][j]=read(); dp(); printf("%lld",re); }
- 1
信息
- ID
- 1187
- 时间
- 909ms
- 内存
- 162MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 25
- 已通过
- 8
- 上传者