题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=3717

题解

这道题大概也就只能算常规的状压 DP 吧,但是这个状态和转移的设计还是不是很好想。

首先很显然,要优先把物品往大的包里面装,直到装不了别人再去装下一个。

可以考虑贪心的策略,如果这个背包还能塞下的话,那么一定要去塞,这样至少是不会差的。

所以令 \(dp[S]\) 表示要装下 \(S\) 中的东西需要多少背包,\(f[S]\) 表示如果要达到 \(dp[S]\) 的结果,那么最后一个背包最多还有多少剩余的空间。

最后 \(dp[Fullset]\) 就是答案。


时间复杂度 \(O(n2^n)\),但是时间限制很充足。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 24 + 7;
const int M = 100 + 7;
const int NP = (1 << 24) + 7;
const int INF = 0x3f3f3f3f; int n, m, S;
int a[N], c[M];
int dp[NP], f[NP]; inline void work() {
std::sort(c + 1, c + m + 1, std::greater<int>());
S = (1 << n) - 1;
memset(dp, 0x3f, sizeof(dp));
dp[0] = 0;
for (int s = 0; s <= S; ++s) {
if (dp[s] == INF) continue;
for (int i = 1; i <= n; ++i) if (!((s >> (i - 1)) & 1)) {
int ss = s | (1 << (i - 1));
if (f[s] < a[i]) {
if (c[dp[s] + 1] >= a[i])
if (smin(dp[ss], dp[s] + 1)) f[ss] = c[dp[ss]] - a[i];
else if (dp[ss] == dp[s] + 1) smax(f[ss], c[dp[ss]] - a[i]);
}
else {
if (smin(dp[ss], dp[s])) f[ss] = f[s] - a[i];
else if (dp[ss] == dp[s]) smax(f[ss], f[s] - a[i]);
}
}
}
if (dp[S] != INF) printf("%d\n", dp[S]);
else puts("NIE");
} inline void init() {
read(n), read(m);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= m; ++i) read(c[i]);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj3717 [PA2014]Pakowanie 贪心+状压DP的更多相关文章

  1. POJ 1795 DNA Laboratory (贪心+状压DP)

    题意:给定 n 个 字符串,让你构造出一个最短,字典序最小的字符串,包括这 n 个字符串. 析:首先使用状压DP,是很容易看出来的,dp[s][i] 表示已经满足 s 集合的字符串以 第 i 个字符串 ...

  2. BZOJ4560 JLOI2016字符串覆盖(kmp+贪心+状压dp+单调队列)

    首先kmp求出每个子串能放在哪些位置.接下来的两部分贪心和状压都可以,各取比较方便的. 最大值考虑贪心.考虑枚举子串的左端点出现顺序,在此基础上每个子串的位置肯定都应该尽量靠前,有是否与上个子串有交两 ...

  3. CodeForces165E 位运算 贪心 + 状压dp

    http://codeforces.com/problemset/problem/165/E 题意 两个整数 x 和 y 是 兼容的,如果它们的位运算 "AND" 结果等于 0,亦 ...

  4. [bzoj3717][PA2014]Pakowanie_动态规划_状压dp

    Pakowanie bzoj-3717 PA-2014 题目大意:给你n个物品m个包,物品有体积包有容量,问装下这些物品最少用几个包. 注释:$1\le n\le 24$,$1\le m\le 100 ...

  5. 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)

    [描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...

  6. Codeforces 429C Guess the Tree(状压DP+贪心)

    吐槽:这道题真心坑...做了一整天,我太蒻了... 题意 构造一棵 $ n $ 个节点的树,要求满足以下条件: 每个非叶子节点至少包含2个儿子: 以节点 $ i $ 为根的子树中必须包含 $ c_i ...

  7. 刷题总结——树有几多愁(51nod1673 虚树+状压dp+贪心)

    题目: lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输 ...

  8. 洛谷P2831 愤怒的小鸟——贪心?状压DP

    题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...

  9. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

随机推荐

  1. 攻防世界 | when_did_you_born

    所以题目要求是输入生日1926 payload: from pwn import * io = remote("111.198.29.45",40803) io.recvline( ...

  2. Fiddler抓包工具-拦截,断点

    1.拦截网页 先拦截请求-F11设置拦截 -F12抓包 2.修改金额 宽带 下行:100M上行:8M 一般家用的都是下行高,企业用都是上下行对等.企业要搭建网站就需要上行. 我们去访问网站,服务器根据 ...

  3. 图论 Algorithms

    1) Dijkstra 基本思路:更新每个点到原点的最短路径:寻找最短路径点进行下一次循环:循环次数达到 n - 1 次说明每个点到原点的最短路已成,停止程序. 1 function Dijkstra ...

  4. sscanf sscanf_s使用

    #include<stdio.h> 定义函数 int sscanf (const char *str,const char * format,........); 函数说明  sscanf ...

  5. codeforces 380A Sereja and Prefixes (递归)

    题目: A. Sereja and Prefixes time limit per test 1 second memory limit per test 256 megabytes input st ...

  6. php面试专题---7、文件及目录处理考点

    php面试专题---7.文件及目录处理考点 一.总结 一句话总结: 用脑子:基本文件操作和目录操作了解一波,不必强求 1.不断在文件hello.txt头部写入一行“Hello World”字符串,要求 ...

  7. 洛谷P2661 信息传递(最小环,并查集)

    洛谷P2661 信息传递 最小环求解采用并查集求最小环. 只适用于本题的情况.对于新加可以使得两个子树合并的边,总有其中一点为其中一棵子树的根. 复杂度 \(O(n)\) . #include< ...

  8. iReport+JasperReport+JSP 输出HTML方式预览

    <%@ page language="java" contentType="text/html; charset=UTF-8"      pageEnco ...

  9. sticky用法

    可以用于滚动到一定距离以后让他实现定位效果. 比如滚动到50px的时候让导航栏固定定位. 用法:给最外层的div设置绝对定位 然后要固定的div设置position:sticky; top:0: 这样 ...

  10. 使用 GitLab 的 OAuth2 认证服务

    原文地址 本文档讲述如何使用 GitLab 作为 OAuth 认证服务提供商,以通过 GitLab 的 OAuth 认证登录其他服务(例如持续集成工具 Drone). 如果想使用其他 OAuth 身份 ...