传送门!node
由于看到$n,m$范围特别小,,,因此直接考虑爆搜$(bushi$
c++
先考虑爆搜以后再想优化什么的嘛$QwQ$ide
首先对这种都要最优的,就能够直接把答案设为针对某一方,而后题目就会变成,轮流的,一次最大一次最小这样子(,,,好像表述得不太好,,,无论了$QAQ$优化
因此直接对每一步枚举全部状态,由于这样最优性的问题显然有每一个状态对应惟一肯定答案,因此直接对每一个状态算出这个状态的答案,而后取最大/最小值就好spa
而后继续考虑,这样显然是会$T$的?3d
因此就记搜一下code
只是考虑记搜怎么存,,,由于这是个轮廓线,因此直接$hash$一下,把轮廓线转化成$m$进制数存到$map$里这样的blog
而后这样彷佛会$T$,,,至少我以前交$T$了$kk$
get
而后咱们最近考试又考到这题了,,,为了不写记搜而后$T$掉我就写了个轮廓线$dp$(也许是轮廓线$dp$,,,?我不知道轮廓线$dp$究竟是啥昂$kk$),就记横0竖1,设$f_i$表示状态$i$以后的全部步数的$min$/$max$,转移下就成hash
其实中心思想差很少?可是快些$QwQ$
而后分别放下那个$80pts$的和$100pts$的$code$趴
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define il inline 4 #define ll long long 5 #define gc getchar() 6 #define ri register int 7 #define rc register char 8 #define rb register bool 9 #define rp(i,x,y) for(ri i=x;i<=y;++i) 10 #define my(i,x,y) for(ri i=x;i>=y;--i) 11 12 const int N=10+5,bas=11,inf=1e9; 13 int n,m,a[N][N],b[N][N],ln[N]; 14 ll poww[N]={1},all; 15 map<ll,int>M; 16 17 il int read() 18 { 19 rc ch=gc;ri x=0;rb y=1; 20 while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; 21 if(ch=='-')ch=gc,y=0; 22 while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; 23 return y?x:-x; 24 } 25 il bool jud(){ri ret=0;rp(i,1,n)ret+=ln[i];return ret&1;} 26 il void unhsh(ll ret){my(i,n,1)ln[i]=ret%bas,ret/=bas;} 27 il ll hsh(){ll ret=0;rp(i,1,n)ret=ret*bas+ln[i];return ret;} 28 int dfs(ll zt) 29 { 30 if(M.count(zt))return M[zt]; 31 unhsh(zt);bool opt=jud();ri ret=opt?inf:-inf; 32 rp(i,1,n) 33 { 34 if(ln[i]>=ln[i-1])continue; 35 ++ln[i];ll nw=hsh(); 36 ret=opt?min(ret,dfs(nw)-b[i][ln[i]]):max(ret,dfs(nw)+a[i][ln[i]]); 37 --ln[i]; 38 } 39 return M[zt]=ret; 40 } 41 42 int main() 43 { 44 // freopen("4363.in","r",stdin);freopen("4363.out","w",stdout); 45 n=read();ln[0]=m=read();rp(i,1,n)rp(j,1,m)a[i][j]=read();rp(i,1,n)rp(j,1,m)b[i][j]=read(); 46 rp(i,1,n)all=all*bas+m;M[all]=0;printf("%d\n",dfs(0)); 47 return 0; 48 }
#include<bits/stdc++.h> using namespace std; #define il inline #define gc getchar() #define ri register int #define rb register bool #define rc register char #define rp(i,x,y) for(ri i=x;i<=y;++i) #define my(i,x,y) for(ri i=x;i>=y;--i) const int N=(1<<21)+1000,M=25,inf=1e9; int n,m,f[N],a[M][M],b[M][M]; struct node{int pos[M],sum;node(){memset(pos,0,sizeof(pos));sum=0;}}; bool vis[N]; il int read() { rc ch=gc;ri x=0;rb y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')ch=gc,y=0; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } il node jy(ri zt) { node nw;ri nwpos=m; while(zt){if(zt&1)++nw.pos[nwpos];else --nwpos,nw.pos[nwpos]=nw.pos[nwpos+1];zt>>=1;} my(i,nwpos-1,1)nw.pos[i]=nw.pos[i+1];rp(i,1,m)nw.sum+=nw.pos[i];return nw; } il int ys(node nw){ri dat=0;rp(i,1,m){dat<<=1;while(nw.pos[i]>nw.pos[i+1])dat=dat<<1|1,--nw.pos[i];}return dat;} int dp(ri zt) { if(zt==(1<<n)-1)return 0;if(vis[zt])return f[zt]; node nw=jy(zt);nw.pos[0]=n; if(!(nw.sum&1)){f[zt]=-inf;rp(i,1,m)if(nw.pos[i-1]>nw.pos[i])++nw.pos[i],f[zt]=max(f[zt],dp(ys(nw))+a[nw.pos[i]][i]),--nw.pos[i];} else{f[zt]=inf;rp(i,1,m)if(nw.pos[i-1]>nw.pos[i])++nw.pos[i],f[zt]=min(f[zt],dp(ys(nw))-b[nw.pos[i]][i]),--nw.pos[i];} vis[zt]=1;return f[zt]; } int main() { //freopen("chess.in","r",stdin);freopen("chess.out","w",stdout); n=read();m=read();rp(i,1,n)rp(j,1,m)a[i][j]=read();rp(i,1,n)rp(j,1,m)b[i][j]=read(); printf("%d\n",dp(0)); return 0; }