转载请注明出处:http://www.cnblogs.com/LadyLex/p/8792894.html
今年的省选题目真是赞啊……Day2的题完全不会做……
不过终于卡着校线爬着进了B队
终于改完了题……在这里总结一下这次的题目吧
DAY1
Pro.1 一双木棋
这道题的确是T1难度的题目……
我们考虑这其实是个对抗搜索
已经放好棋子的位置只能是左上角,并且从上到下是不降的
如果我维护了现在已经放了棋子的位置,我就可以知道下一步该谁放,以及哪里可以放了
具体做法……我用11进制压位来着,出题人的做法是用01维护轮廓线
hashmap快的飞起
code:
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define RG register 5 #define LL long long 6 #define mod 612497 7 #define inf 0x3f3f3f3f 8 struct hash_map 9 { 10 struct node{LL state;int next,val;}s[200000]; 11 int e,adj[mod]; 12 inline void ins(LL state,int val) 13 { 14 RG int pos=state%mod; 15 s[++e].state=state;s[e].val=val;s[e].next=adj[pos];adj[pos]=e; 16 } 17 inline int get(LL state) 18 { 19 RG int pos=state%mod,i; 20 for(i=adj[pos];i&&s[i].state!=state;i=s[i].next); 21 if(!i)return -inf; 22 return s[i].val; 23 } 24 }H; 25 inline int min(int a,int b){return a<b?a:b;} 26 inline int max(int a,int b){return a>b?a:b;} 27 int n,m,A[15][15],B[15][15]; 28 LL bin[20]; 29 inline int dfs(int l,int r,LL state,int already) 30 { 31 if(already==n*m)return 0; 32 int ret=H.get(state); 33 if(ret!=-inf)return ret; 34 if(already&1)ret=inf; 35 int last=0; 36 for(RG int i=l;i<=r;++i) 37 { 38 int v=(state/bin[i-1])%11; 39 if(i!=l&&v==last)continue; 40 if(already&1)ret=min(ret,-B[i][v+1]+dfs(l+(v==m-1),r,state+bin[i-1],already+1)); 41 else ret=max(ret,A[i][v+1]+dfs(l+(v==m-1),r,state+bin[i-1],already+1)); 42 last=v; 43 } 44 if(r<n) 45 if(already&1)ret=min(ret,-B[r+1][1]+dfs(l,r+1,state+bin[r],already+1)); 46 else ret=max(ret,A[r+1][1]+dfs(l,r+1,state+bin[r],already+1)); 47 H.ins(state,ret); 48 return ret; 49 } 50 int main() 51 { 52 RG int i,j; 53 scanf("%d%d",&n,&m); 54 for(bin[0]=i=1;i<=15;++i) 55 bin[i]=bin[i-1]*11ll; 56 for(i=1;i<=n;++i) 57 for(j=1;j<=m;++j) 58 scanf("%d",&A[i][j]); 59 for(i=1;i<=n;++i) 60 for(j=1;j<=m;++j) 61 scanf("%d",&B[i][j]); 62 if(m==1) 63 { 64 int ans=0; 65 for(i=1;i<=n;++i) 66 if(i&1)ans+=A[i][1]; 67 else ans-=B[i][1]; 68 printf("%d\n",ans); 69 return 0; 70 } 71 printf("%d\n",A[1][1]+dfs(1,1,1,1)); 72 }