基本的状态压缩,想明白怎么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 ", 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. ", (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 " % (t)) 12 for tt in xrange(t): 13 n = randint(1, 10) 14 fout.write("%d " % (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)) + " ") 20 21 22 def MovDataIn(): 23 desFileName = "F:eclipse_prjworkspacehdojdata.in" 24 shutil.copyfile("data.in", desFileName) 25 26 27 if __name__ == "__main__": 28 GenDataIn() 29 MovDataIn()