FZU Problem 1686 神龙的难题 重复覆盖
2015-12-16 12:36
417 查看
题目链接
给出大矩形的长宽, 矩形里面有1,0两个值, 给出小矩形的长宽, 求用最少的小矩形覆盖所有的1.
重复覆盖的模板题。
给出大矩形的长宽, 矩形里面有1,0两个值, 给出小矩形的长宽, 求用最少的小矩形覆盖所有的1.
重复覆盖的模板题。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 305; const int maxNode = 5000; struct DLX { int L[maxNode], R[maxNode], U[maxNode], D[maxNode], row[maxNode], col[maxNode]; int S[maxn], H[maxn], deep, ans[maxn], sz, n, m, k, n1, m1; int g[20][20]; void remove(int c) { for(int i = D[c]; i!=c; i = D[i]) { L[R[i]] = L[i]; R[L[i]] = R[i]; } } void resume(int c) { for(int i = U[c]; i!=c; i = U[i]) { L[R[i]] = i; R[L[i]] = i; } } int h() { int cnt = 0; int vis[250]; mem(vis); for(int i = R[0]; i!=0; i = R[i]) { if(!vis[i]) { cnt++; vis[i] = 1; for(int j = D[i]; j!=i; j = D[j]) { for(int k = R[j]; k!=j; k = R[k]) { vis[col[k]] = 1; } } } } return cnt; } void dfs(int d) { if(d+h()>=deep) return ; if(R[0] == 0) { deep = min(deep, d); return ; } int c = R[0]; for(int i = R[0]; i!=0; i = R[i]) if(S[c]>S[i]) c = i; for(int i = D[c]; i!=c; i = D[i]) { remove(i); for(int j = R[i]; j!=i; j = R[j]) remove(j); dfs(d+1); for(int j = L[i]; j!=i; j = L[j]) resume(j); resume(i); } return ; } void add(int r, int c) { sz++; row[sz] = r; col[sz] = c; S[c]++; U[sz] = U[c]; D[sz] = c; D[U[c]] = sz; U[c] = sz; if(~H[r]) { R[sz] = H[r]; L[sz] = L[H[r]]; L[R[sz]] = sz; R[L[sz]] = sz; } else { H[r] = L[sz] = R[sz] = sz; } } void init(){ mem1(H); for(int i = 0; i<=n; i++) { R[i] = i+1; L[i] = i-1; U[i] = i; D[i] = i; } deep = inf; mem(S); R = 0; L[0] = n; sz = n; } void solve() { mem(g); int cnt = 0, x; for(int i = 0; i<n; i++) { for(int j = 0; j<m; j++) { scanf("%d", &x); if(x) g[i][j] = ++cnt; else g[i][j] = 0; } } scanf("%d%d", &n1, &m1); int r = 0, tmp = n; n = cnt; init(); for(int i = 0; i<tmp-n1+1; i++) { for(int j = 0; j<m-m1+1; j++) { r++; for(int k1 = i; k1<min(i+n1, tmp); k1++) { for(int k2 = j; k2<min(j+m1, m); k2++) { if(g[k1][k2]) { add(r, g[k1][k2]); } } } } } dfs(0); printf("%d\n", deep); } }dlx; int main() { while(scanf("%d%d", &dlx.n, &dlx.m)!=EOF) { dlx.solve(); } return 0; }
相关文章推荐
- Android编程之ICS式下拉菜单PopupWindow实现方法详解(附源码下载)
- OC-050.常用的结构体
- 使用 hadoop组件 作为 ETL 或 ELT 工具
- wubi安装ubuntu的正确方法
- leetcode -- Basic Calculator I &II --重点,未完全理解
- GPS定位系统的介绍
- 编译器错误消息: CS0016: 未能写入输出文件
- Objective-C_OC中的方法
- 【第四篇章-android平台MediaCodec】推断是否支持硬件解码码
- LeetCode Palindrome Number
- mysql 查询优化
- 栈的顺序表示和实现
- linux select例子
- 设计模式:0. 设计原则
- Unity Networking API文档翻译(二):The High Level API
- ssh -CT -o BatchMode=yes 用户名@主机名
- 考拉社区深度打造“智鲜乐”生活社区
- 修改IOS程序名称
- Ubuntu/Linux apache启动、重启、停止操作指令
- 欢迎使用CSDN-markdown编辑器