傳送門!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; }