Luogu4363 [九省聯考2018]一雙木棋chess 【狀壓DP】【進制轉換】
阿新 • • 發佈:2019-02-23
\n number ace bsp con pac sin 狀壓dp ++
題目分析:
首先跑個暴力,求一下有多少種狀態,發現只有18xxxx種,然後每個狀態有10的轉移,所以復雜度大約是200w,然後利用進制轉換的技巧求一下每個狀態的十進制碼就行了。
代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n,m; 5 6 int A[12][12],B[12][12]; 7 int kk[12][12]; // after number 8 9 int f[201000],arr[201000]; 10 11 int sit[12]; 12 13 int calc(){ 14 intans = 0; 15 for(int i=1;i<=n;i++){ans += kk[i][sit[i]-1];} 16 return ans+1; 17 } 18 19 int dfs(int dr){ 20 int z = calc(); 21 if(arr[z]) return f[z]; 22 arr[z] = 1; f[z] = -1e9; 23 for(int i=1;i<=n;i++){ 24 if(sit[i] == m) continue; 25 if(i != 1 && sit[i] == sit[i-1]) continue; 26 sit[i]++; 27 f[z] = max(f[z],(dr==1?A[i][sit[i]]:B[i][sit[i]])-dfs(dr^1)); 28 sit[i]--; 29 } 30 return f[z]; 31 } 32 33 void read(){ 34 scanf("%d%d",&n,&m); 35 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&A[i][j]); 36 for(inti=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&B[i][j]); 37 } 38 39 void work(){ 40 for(int i=1;i<=m;i++) kk[n+1][i] = 1; 41 for(int i=n;i>=1;i--){ 42 kk[i][0] = 1; 43 for(int j=1;j<=m;j++) kk[i][j] = kk[i][j-1]+kk[i+1][j]; 44 } 45 f[kk[1][m]] = 0; arr[kk[1][m]] = 1; 46 f[1] = dfs(1); 47 printf("%d\n",f[1]); 48 } 49 50 int main(){ 51 read(); 52 work(); 53 return 0; 54 }
Luogu4363 [九省聯考2018]一雙木棋chess 【狀壓DP】【進制轉換】