基本的状态压缩,想明白怎么dp还是挺简单的。
显然对n个数字进行状态压缩,dp[i][j]表示第i位状态j表示的位向高位产生了进位。
/* 4317 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int INF = 0x3f3f3f3f;
int dp[][(<<)+];
int Bit[];
int a[];
int C[(<<)+];
int n; int getBit(int x) {
int ret = ; while (x) {
ret += (x & );
x >>= ;
} return ret;
} void Init() {
int mst = <<;
rep(i, , mst)
C[i] = getBit(i);
} void solve() {
rep(j, , ) {
Bit[j] = ;
rep(i, , n) {
if (a[i] & (<<j))
Bit[j] |= (<<i);
}
} memset(dp, INF, sizeof(dp));
dp[][] = ;
int mst = <<n;
int mask = mst - ;
int ans, tmp; rep(i, , ) {
rep(j, , mst) {
if (dp[i][j] == INF)
continue; int ov = j & Bit[i];
int one = Bit[i] ^ j;
int zero = mask & ~one;
rep(k, , mst) {
if (ov & ~k)
continue; int other_ov = k & ~ov;
if (other_ov & zero)
continue; tmp = C[other_ov];
int val = one ^ other_ov;
if (C[val] & ) {
if (val == mask)
continue;
++tmp;
} tmp <<= i;
dp[i+][k] = min(dp[i+][k], tmp+dp[i][j]);
}
}
} ans = dp[][];
if (ans == INF)
puts("impossible");
else
printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif Init();
while (scanf("%d", &n)!=EOF) {
rep(i, , n)
scanf("%d", &a[i]);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}
数据发生器。
from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t =
bound = **
# fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(, )
fout.write("%d\n" % (n))
dataList = []
for i in xrange(n):
x = randint(, bound)
dataList.append(x)
fout.write(" ".join(map(str, dataList)) + "\n") def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()