http://acm.hdu.edu.cn/showproblem.php?pid=4212
论文写烦了,水了一道很水的状压DP,状态很稀疏用map搞下,预处理很关键。
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <map> #include <string> #include <algorithm> #include <utility> #include <list> #include <fstream> #include <cctype> #include <vector> #include <cmath> #include <climits> #include <ctime> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef unsigned UN; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; typedef long double LF; const int MAXN(300010); const int MAXM(20010); const int MAXE(210); const int MAXK(6); const int HSIZE(313131); const int SIGMA_SIZE(26); const int MAXH(19); const int INFI((INT_MAX-1) >> 1); const ULL BASE(31); const LL LIM(1e13); const int INV(-10000); const int MOD(1000000007); const double EPS(1e-7); const LF PI(acos(-1.0)); template<typename T> inline bool checkmax(T &a, T b){if(b > a) { a = b; return true;} return false;} template<typename T> inline bool checkmin(T &a, T b){if(b < a) { a = b; return true;} return false;} template<typename T> inline T ABS(T a){return a < 0? -a: a;} template<typename T> inline bool EZ(T a){return ABS(a) < EPS;} struct HASH_MAP{ int first[HSIZE]; int state[MAXN], val[MAXN], next[MAXN], size; void init(){ memset(first, -1, sizeof(first)); size = 0; } void insert(int ts, int tv){ int h = ts%HSIZE; for(int i = first[h]; ~i; i = next[i]) if(ts == state[i]) return; state[size] = ts; val[size] = tv; next[size] = first[h]; first[h] = size++; } } hm[2], *cur, *last; vector<PAIR> vec[23][23]; void dfs(int dep, int st, int v, int cnt){ if(v > 22) return; if(v > 0) vec[dep-1][v].push_back(PAIR(st, cnt)); if(dep == 23) return; dfs(dep+1, st, v, cnt); dfs(dep+1, st|(1 << dep), v+dep, cnt+1); } int main(){ dfs(1, 0, 0, 0); int N, T, n_case(0); while(~scanf("%d%d", &N, &T), N+T){ vector<PAIR> *vp = vec[N]; cur = hm; last = hm+1; last->init(); last->insert(0, 0); int ans = 0; int temp; for(int i = 0; i < T; ++i){ scanf("%d", &temp); cur->init(); for(vector<PAIR>::iterator it = vp[temp].begin(); it != vp[temp].end(); ++it){ int sz = last->size; for(int j = 0; j < sz; ++j) if((last->state[j]&it->first) == 0){ int tv = last->val[j]+it->second; checkmax(ans, tv); cur->insert(last->state[j]+it->first, tv); } } swap(cur, last); } printf("Game %d: %d\n", ++n_case, ans); } return 0; }