5248: [2018多省省队联测]一双木棋
5248: [2018多省省队联测]一双木棋
分析:
极大极小搜索!记忆化一下,所有的状态是阶梯状的!然后缩成一个LL。
好像状压dp也行。
考试的时候。。。啥都不会。。。不会极大极小搜索,不会dp,不会这道题!
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 20; 11 const LL base = 11; 12 int a[N][N],b[N][N],sta[N],n,m; 13 map<LL,int> p; 14 15 inline LL getHash() { 16 LL ret = 0; 17 for (int i=1; i<=n; ++i) ret = ret * base + sta[i]; 18 return ret; 19 } 20 inline void getState(LL S) { 21 for (int i=n; i>=1; --i) sta[i] = S % base,S /= base; 22 } 23 int Minimax(int player,LL S) { 24 if (p.find(S) != p.end()) return p[S]; 25 getState(S); 26 int res = player ? 1e9 : -1e9; 27 for (int i=1; i<=n; ++i) { 28 if (sta[i-1] > sta[i]) { 29 ++ sta[i]; 30 LL T = getHash(); 31 if (!player) res = max(res,Minimax(player^1,T) + a[i][sta[i]]) ; 32 else res = min(res,Minimax(player^1,T) - b[i][sta[i]]) ; 33 -- sta[i]; 34 } 35 } 36 p[S] = res; 37 return res; 38 } 39 40 int main() { 41 n = read(),m = read(); 42 for (int i=1; i<=n; ++i) 43 for (int j=1; j<=m; ++j) a[i][j] = read(); 44 for (int i=1; i<=n; ++i) 45 for (int j=1; j<=m; ++j) b[i][j] = read(); 46 47 for (int i=1; i<=n; ++i) sta[i] = m; 48 p[getHash()] = 0; 49 50 sta[0] = m; 51 52 cout << Minimax(0,0); 53 54 return 0; 55 }