Description

你有n个物品和m个包。物品有重量,且不可被分割;包也有各自的容量。要把所有物品装入包中,至少需要几个包?

Input

第一行两个整数n,m(1<=n<=24,1<=m<=100),表示物品和包的数量。
第二行有n个整数a[1],a[2],…,a[n](1<=a[i]<=10^8),分别表示物品的重量。
第三行有m个整数c[1],c[2],…,c[m](1<=c[i]<=10^8),分别表示包的容量。

Output

如果能够装下,输出一个整数表示最少使用包的数目。若不能全部装下,则输出NIE。

Sample Input

4 3
4 2 10 3
11 18 9

Sample Output

2

HINT

Source

鸣谢Jcvb

n很小,考虑状压;

首先背包肯定是要从大往小用的,sort一遍;

我们在dp转移的时候需要知道3个量:

用到第几个背包了,当前背包的剩余容量,已经放好的集合状态;

我们用num[zt]表示放zt的物品用到第几个背包了,用hav[zt]表示放zt的物品已经用了多少容量,sum[num[zt]-hav[zt]就是当前背包剩余的容量;

放入一个物品的转移分两种:

1.当前背包还能放,那么直接放;

2.当前背包放不了,那么新开一个背包;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100050;
const int Inf=19260817;
int num[1<<24],w[200],n,m;
ll sum[200],hav[1<<24];
bool cmp(int a,int b){return a>b;}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
for(int i=1;i<=m;i++) scanf("%lld",&sum[i]);
sort(sum+1,sum+1+m,cmp);
for(int i=1;i<=m;i++) sum[i]=sum[i-1]+sum[i];
m=min(n,m);
for(int i=1;i<1<<n;i++) hav[i]=3e12,num[i]=Inf;
for(int zt=0;zt<1<<n;zt++){
if(hav[zt]==3e12) continue;
for(int j=0;j<n;j++){
if(!(zt&(1<<j))){
int k=zt+(1<<j);
if(sum[num[zt]]-hav[zt]<w[j+1]){
if(sum[num[zt]]+w[j+1]<hav[k]){
if(num[zt]==m||sum[num[zt]+1]-sum[num[zt]]<w[j+1]) continue;
hav[k]=sum[num[zt]]+w[j+1];
num[k]=num[zt]+1;
}
}
else{
if(hav[zt]+w[j+1]<hav[k]){
hav[k]=hav[zt]+w[j+1];num[k]=num[zt];
}
}
}
}
}
if(num[(1<<n)-1]==Inf) puts("NIE");
else cout<<num[(1<<n)-1]<<endl;
return 0;
}

bzoj 3717: [PA2014]Pakowanie的更多相关文章

  1. [PA2014]Pakowanie

    [PA2014]Pakowanie 题目大意: \(n(n\le24)\)个物品和\(m(m\le100)\)个背包,每个物体有一个体积\(a_i\),每个背包有一个容量\(c_i\).问装完所有物品 ...

  2. BZOJ 3721: PA2014 Final Bazarek

    3721: PA2014 Final Bazarek Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 645  Solved: 261[Submit][ ...

  3. BZOJ 3709: [PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1050  Solved: ...

  4. 【贪心】bzoj 3709:[PA2014]Bohater

    3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved:  ...

  5. BZOJ 3713: [PA2014]Iloczyn( 枚举 )

    斐波那契数列<10^9的数很少很少...所以直接暴力枚举就行了... ------------------------------------------------------------- ...

  6. bzoj 3714 [PA2014]Kuglarz 最小生成树

    [PA2014]Kuglarz Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1335  Solved: 672[Submit][Status][Di ...

  7. bzoj 3722: PA2014 Final Budowa

    3722: PA2014 Final Budowa Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 303  Solved: 108[Submit][St ...

  8. BZOJ 3712: [PA2014]Fiolki 倍增+想法

    3712: [PA2014]Fiolki Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 437  Solved: 115[Submit][Status ...

  9. bzoj3717 [PA2014]Pakowanie 贪心+状压DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3717 题解 这道题大概也就只能算常规的状压 DP 吧,但是这个状态和转移的设计还是不是很好想. ...

随机推荐

  1. CCF考试认证模拟练习——数字排序

    #include<iostream>#include<algorithm>using namespace std;struct node //定义结构体{ int num;// ...

  2. 设置SO_RECVBUF和SO_SENDBUF套接字选项

    控制套接字的行为(如修改缓冲区的大小). int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen) ...

  3. Numpy入门 - 数组聚合运算

    本节主要讲解numpy的几个常用的聚合运算,包括求和sum.求平均mean和求方差var. 一.求和sum import numpy as np arr = np.array([[1, 2, 3], ...

  4. Ocelot网关

    Ocelot是一个.net core框架下的网关的开源项目,下图是官方给出的基础实现图,即把后台的多个服务统一到网关处,前端应用:桌面端,web端,app端都只用访问网关即可. Ocelot的实现原理 ...

  5. C# 使用Task实现任务超时,多任务一起执行

    简介:充分使用Task的异步功能代码实现:1.实现了任务超时 退出任务 2.多个任务一起执行 /// <summary>        ///做事 需要 ms秒 才能完成        / ...

  6. eclipse 常用插件 整理

    开发过程中的常用Eclipse插件,按字母排序: (1)    AmaterasUML        介绍:Eclipse的UML插件,支持UML活动图,class图,sequence图,usecas ...

  7. nyoj 2 括号配对问题 栈

    nyoj 2 括号配对问题 题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=2 思路: 栈:'(' '['入栈,遇到 ']' ')'出栈 ...

  8. 51nod 1020 逆序排列 DP

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...

  9. 移动GIS未来的前景GIS解决方案应用

    目前,在我国一些发达地区,移动GIS所需的两个技术前提——移动互联网的普及和智能终端的普及都已经得到了满足,特别是平板电脑.智能手机的流行,苹果产品的风靡,为移动GIS的应用提供了肥沃的土壤,而GIS ...

  10. tomcat8权限分离

    安装jdk tar xf jdk-8u121-linux-x64.tar.gz mv jdk-*  /usr/local/jdk1.8 vi /etc/profile export JAVA_HOME ...