转载请注明出处: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 }
chess

相关文章: