【HDOJ】4317 Unfair Nim

基本的状态压缩,想明白怎么dp还是挺简单的。
显然对n个数字进行状态压缩,dp[i][j]表示第i位状态j表示的位向高位产生了进位。

  1 /* 4317 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 const int INF = 0x3f3f3f3f;
 44 int dp[23][(1<<10)+5];
 45 int Bit[23];
 46 int a[15];
 47 int C[(1<<10)+5];
 48 int n;
 49 
 50 int getBit(int x) {
 51     int ret = 0;
 52     
 53     while (x) {
 54         ret += (x & 1);
 55         x >>= 1;
 56     }
 57     
 58     return ret;
 59 }
 60 
 61 void Init() {
 62     int mst = 1<<10;
 63     rep(i, 0, mst)
 64         C[i] = getBit(i);
 65 }
 66 
 67 void solve() {
 68     rep(j, 0, 22) {
 69         Bit[j] = 0;
 70         rep(i, 0, n) {
 71             if (a[i] & (1<<j))
 72                 Bit[j] |= (1<<i);
 73         }
 74     }
 75     
 76     memset(dp, INF, sizeof(dp));
 77     dp[0][0] = 0;
 78     int mst = 1<<n;
 79     int mask = mst - 1;
 80     int ans, tmp;
 81     
 82     rep(i, 0, 22) {
 83         rep(j, 0, mst) {
 84             if (dp[i][j] == INF)
 85                 continue;
 86             
 87             int ov = j & Bit[i];
 88             int one = Bit[i] ^ j;
 89             int zero = mask & ~one;
 90             rep(k, 0, mst) {
 91                 if (ov & ~k)
 92                     continue;
 93                 
 94                 int other_ov = k & ~ov;
 95                 if (other_ov & zero)
 96                     continue;
 97                 
 98                 tmp = C[other_ov];
 99                 int val = one ^ other_ov;
100                 if (C[val] & 1) {
101                     if (val == mask)
102                         continue;
103                     ++tmp;
104                 }
105                 
106                 tmp <<= i;
107                 dp[i+1][k] = min(dp[i+1][k], tmp+dp[i][j]);
108             }
109         }
110     }
111             
112     ans = dp[22][0];
113     if (ans == INF)
114         puts("impossible");
115     else
116         printf("%d\n", ans);
117 }
118 
119 int main() {
120     ios::sync_with_stdio(false);
121     #ifndef ONLINE_JUDGE
122         freopen("data.in", "r", stdin);
123         freopen("data.out", "w", stdout);
124     #endif
125     
126     Init();
127     while (scanf("%d", &n)!=EOF) {
128         rep(i, 0, n)
129             scanf("%d", &a[i]);
130         solve();
131     }
132     
133     #ifndef ONLINE_JUDGE
134         printf("time = %d.\n", (int)clock());
135     #endif
136     
137     return 0;
138 }

数据发生器。

 1 from copy import deepcopy
 2 from random import randint, shuffle
 3 import shutil
 4 import string
 5 
 6 
 7 def GenDataIn():
 8     with open("data.in", "w") as fout:
 9         t = 20
10         bound = 10**6
11         # fout.write("%d\n" % (t))
12         for tt in xrange(t):    
13             n = randint(1, 10)
14             fout.write("%d\n" % (n))
15             dataList = []
16             for i in xrange(n):
17                 x = randint(1, bound)
18                 dataList.append(x)
19             fout.write(" ".join(map(str, dataList)) + "\n")
20             
21                 
22 def MovDataIn():
23     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
24     shutil.copyfile("data.in", desFileName)
25 
26     
27 if __name__ == "__main__":
28     GenDataIn()
29     MovDataIn()

 

你可能感兴趣的:(【HDOJ】4317 Unfair Nim)