[hdu4285 circuits] 插头dp
来源:互联网 发布:绝地求生n卡优化 编辑:程序博客网 时间:2024/04/29 21:03
题意:一个n*m的01矩阵,用刚好k个回路覆盖所有的1,回路之间不能相互包含、交叉,求方法总数。
思路:又1个回路问题,与单回路和多回路问题不同,这题限制了回路个数,那么把回路个数加进状态里面,在转移的时候维护下即可。具体来说,采用8进制表示连通性,用最小表示法将状态编码,dp时用hash保存一个阶段的所有状态。
#include <bits/stdc++.h>using namespace std;#ifndef ONLINE_JUDGE#include "local.h"#endif // ONLINE_JUDGE#define pb(x) push_back(x)#define mp(x, y) make_pair(x, y)#define all(a) (a).begin(), (a).end()#define mset(a, x) memset(a, x, sizeof(a))#define mcpy(a, b) memcpy(a, b, sizeof(b))#define up(a, b) for (int a = 0; a < (b); a ++)#define down(a, b) for (int a = b - 1; (a) >= 0; a --)#define rep(i, a, b) for (int i = a; i <= (b); i ++)#define rrep(i, a, b) for (int i = a; i >= (b); i --)#define cas() int T, cas = 0; cin >> T; while (T --)#define printCas(ch) printf("Case #%d:%c", ++ cas, ch)#define watch(ele) cout << ele << endl;#define in(a) scanf("%d", &a)typedef long long ll;typedef pair<int, int> pii;template<typename T>bool umax(T&a, const T&b){return a<b?(a=b,true):false;}template<typename T>bool umin(T&a, const T&b){return b<a?(a=b,true):false;}const int mod = 1e9 + 7;const int N = 15007;struct HashMap { int head[N]; ll key[N]; int value[N][40]; int nxt[N]; int sz; HashMap() {clear();} void clear() { sz = 0; mset(head, -1); mset(value, 0); } int push(ll state, int c, int val) { int pos = state % N, i = head[pos]; for (; ~i; i = nxt[i]) { if (key[i] == state) { value[i][c] += val; if (value[i][c] >= mod) value[i][c] -= mod; return i; } } if (i == -1) { value[sz][c] = val; key[sz] = state; nxt[sz] = head[pos]; head[pos] = sz ++; return sz - 1; } }};HashMap dp[2];int code[15], code2[15];char used[10], id[10];int n, m, K, c, row, col, newk, maxid, val, cur;ll ans;char s[22][22];ll encode(int a[]) { ans = 0; rrep(i, m, 0) { ans = ans << 3 | a[i]; } return ans;}void decode(int a[], ll state) { rep(i, 0, m) { a[i] = state & 7; state >>= 3; }}bool chk() { c = 0; rep(i, 0, col - 1) rep(j, col + 1, m - 1) { if (code[i] && code[i] == code[j]) c ^= 1; } return c == 0;}void relax() { mset(used, 1); c = 1; rep(i, 0, m) { if (code2[i] && used[code2[i]]) id[code2[i]] = c ++; used[code2[i]] = 0; } rep(i, 0, m) code2[i] = id[code2[i]];}void merge() { up(i, m) { if (i != col && code[i] == code[col]) code2[i] = code[m]; } code2[m] = code2[col] = 0; if (code[m] == code[col]) newk ++; relax();}void turn() { code2[m] = code[col]; code2[col] = code[m]; relax();}void create() { maxid = 0; up(i, m) umax(maxid, code[i]); code2[m] = code2[col] = maxid + 1; relax();}#define update() dp[cur ^ 1].push(encode(code2), newk, val)void trans() { if (s[row][col] == '*' && (code[m] || code[col])) return; if (col == 0 && code[m]) return; if (code[m] && code[col]) { if (code[m] == code[col]) { if (chk()) { merge(); update(); } } else { merge(); update(); } } if (code[m] && !code[col] || !code[m] && code[col]) { update(); turn(); update(); } if (!code[m] && !code[col]) { if (s[row][col] == '*') update(); else { create(); update(); } }}int work() { if (K > n * m / 4) return 0; cur = 0; dp[0].clear(); dp[1].clear(); dp[0].push(0, 0, 1); up(i, n) up(j, m) { up(k, dp[cur].sz) up(p, K + 1) { decode(code, dp[cur].key[k]); memcpy(code2, code, sizeof(code2)); newk = p; val = dp[cur].value[k][p]; row = i; col = j; if (val) trans(); } dp[cur].clear(); cur ^= 1; } return dp[cur].value[dp[cur].push(0, K, 0)][K];}int main() {#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout);#endif // ONLINE_JUDGE cas() { cin >> n >> m >> K; up(i, n) scanf("%s", s[i]); cout << work() << endl; } return 0;}
0 0
- [hdu4285 circuits] 插头dp
- HDU4285 circuits 插头dp
- HDU 4285 circuits[插头DP]
- hdu 4285 circuits 插头dp
- HDOJ 4285 circuits (插头dp 总结)
- HDU 4285 circuits 解题报告(插头DP)
- HDU 4285 circuits(回路不能嵌套的插头DP)
- hdu 4285 circuits(插头DP多条回路无嵌套环)
- 插头DP
- 插头dp
- 插头dp
- 插头dp
- 插头DP
- 插头dp
- hdu 1693 插头dp
- 插头DP【入门】
- hdu 4064 (插头DP)
- poj 3133 插头Dp
- python计算分位数
- centos7-uninstall vmware
- poj-1979改-红与黑
- shell 编程手记
- 资源管理系统
- [hdu4285 circuits] 插头dp
- Unity项目结构和版本控制
- Unity C#脚本热更
- isalpha判断字母函数的使用
- HDU 4347 The Closest M Points
- 文章标题
- python对文件及文件夹的一些操作
- 二分查找(折半查找)
- C标准库没提供的助手函数:字符串替换