状压DP问题
来源:互联网 发布:网络约车平台 计划书 编辑:程序博客网 时间:2024/06/06 10:04
状态压缩·一
题目传送:#1044 : 状态压缩·一
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;int n, m, q;int w[1005];int dp[1005][1030];//dp[i][j]表示选到第i个位置时j状态能够取得的最大值int cnt[1030];//代表每个数的位数上的1的个数int main() { cnt[0] = 0, cnt[1] = 1; for(int i = 2; i < 1030; i ++) cnt[i] = cnt[i >> 1] + cnt[i & 1]; scanf("%d %d %d", &n, &m, &q); for(int i = 1; i <= n; i ++) { scanf("%d", &w[i]); } int ans = 0; int d = 1 << m; for(int i = 1; i <= n; i ++) { for(int j = 0; j < (1 << m); j ++) { if(cnt[j] <= q) dp[i][j] = max(dp[i-1][j >> 1], dp[i-1][(j >> 1) + (1 << (m - 1))]) + (j & 1) * w[i]; ans = max(ans, dp[i][j]); } } printf("%d\n", ans); return 0;}
Hackers’ Crackdown
题目传送:UVA - 11825 - Hackers’ Crackdown
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = (1 << 16) + 5;int dp[maxn];//dp[i]表示子集i最多可以分成多少组int cover[maxn];//cover[i]表示若干集合(i中所表示的集合)的并集int n, m;int P[25];//P[i]表示与i相连的数的集合(包括i)int main() { int cas = 1; while(scanf("%d", &n) != EOF) { if(n == 0) break; for(int i = 0; i < n; i ++) { scanf("%d", &m); P[i] = 1 << i; int t; while(m --) { scanf("%d", &t); P[i] |= (1 << t);//并入集合i } } for(int i = 0; i < maxn; i ++) { cover[i] = 0; for(int j = 0; j < n; j ++) {//if判断j是否在i中,是得话就并入 if(i & (1 << j)) cover[i] |= P[j]; } } dp[0] = 0; int tot = (1 << n) - 1;//全集总数 for(int i = 1; i <= tot; i ++) {//依次枚举全集,因为要先算出前一状态才能推出后一状态 dp[i] = 0; for(int j = i; j; j = (j - 1) & i) {//枚举子集的技巧,重点! if(cover[j] == tot) {//i的子集j等于全集,则执行状态转移 dp[i] = max(dp[i], dp[i ^ j] + 1); } } } printf("Case %d: %d\n", cas ++, dp[tot]); } return 0;}
Sharing Chocolate
题目传送:UVALive - 4794 - Sharing Chocolate
WF2010的题。
AC代码:
#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 16;int d[1 << maxn][105];int vis[1 << maxn][105];int sum[1 << maxn];int a[maxn];int n;int bitcount(int x) { return x == 0 ? 0 : bitcount(x / 2) + (x & 1);}int dp(int s, int x) {//每次递归找出集合为s,宽为x的巧克力是否可以满足要求 if(vis[s][x]) return d[s][x]; vis[s][x] = 1; int& ans = d[s][x]; if(bitcount(s) == 1) return ans = 1;//此时为边界,即只有一块巧克力的情况,肯定是满足的 int y = sum[s] / x;//另一个边长可以根据这个求得 for(int s0 = (s - 1) & s; s0; s0 = (s0 - 1) & s) {//枚举子集 int s1 = s - s0; if(sum[s0] % x == 0 && dp(s0, min(x, sum[s0] / x)) && dp(s1, min(x, sum[s1] / x))) return ans = 1;//竖着切(这里假定宽x是竖着的) if(sum[s0] % y == 0 && dp(s0, min(y, sum[s0] / y)) && dp(s1, min(y, sum[s1] / y))) return ans = 1;//横着切 } return ans = 0;}int main() { int cas = 1, x, y; while(scanf("%d", &n) != EOF) { if(n == 0) break; scanf("%d %d", &x, &y); for(int i = 0; i < n; i ++) scanf("%d", &a[i]); //计算每个子集的元素的和 memset(sum, 0, sizeof(sum)); for(int s = 0; s < (1 << n); s ++) { for(int i = 0; i < n; i ++) if(s & (1 << i)) sum[s] += a[i]; } memset(vis, 0, sizeof(vis)); int ALL = (1 << n) - 1; int ans; if(sum[ALL] != x * y) ans = 0; else ans = dp(ALL, min(x, y)); printf("Case %d: %s\n", cas ++, ans ? "Yes" : "No"); } return 0;}
0 0
- 状压DP问题
- HDU_3681 TSP问题,状压DP
- poj3311 TSP问题 状压DP
- TSP问题(状压DP求解)
- 状压DP<旅行商问题>
- DP问题
- DP问题
- dp问题
- DP问题
- DP 问题
- POJ1321 棋盘问题(DFS||状压DP)
- Node:状压DP-1(棋子问题)
- 点集配对问题 状压DP
- poj 2411 骨牌覆盖问题 状压dp
- 点集配对问题(状压dp)
- POJ1321:棋盘问题(状压dp & DFS)
- 状压dp - 棋盘问题(学习)
- hdu 3001 Travelling (TSP问题,状压dp)
- [网狐]6603后台最高管理员密码修改
- Android WebView 因重定向无法正常goBack()解决方案
- poj- 2002-Squares-哈希|除法散列法
- java自学之路--开始就需要摸清楚的环境配置和JDK细节
- Swift版 ScrollView和UITouch事件冲突
- 状压DP问题
- iOS 简单使用富文本格式对一个字符串进行不同设置
- sobel和laplace算子
- Linux____文件的压缩与打包学习笔记
- sublime快捷键
- OC继承的工作机制。
- Eclipse代码整体后退或前移
- 首次涉水Maven+Jersey,入门笔记
- 黑马程序员--java基础--网络编程TCP传输