Relocation poj-2923

    题目大意:给出n个物品,有两辆车,两辆车必须一起出动并且每辆车有单独的容量。问最少需要运输多少次才能运走所有货物。

    注释:n<=10,容量,物品代价<=1000且物品代价<=max(两车容量)。

      想法:这题的入手比较的容易,之后的方法会直接影响代码美观性和时间效率。首先,我们通过简单的状态压缩以及状态表示统计出两辆车分别的可以单次承载的状态,比如此时第一辆车有cnt1种,第二辆车有cnt2种,然后我们通过暴力枚举两辆车所有的状态统计出两辆车一起行动所能承载的所有状态,由于两辆车是一起行动,所以这样的处理是恰到好处的。之后的方法就很重要,我当时tm脑袋一热——爆搜!完了就够jb呛了。不做介绍,我们介绍dp做法:

        状态:dp[i]表示运走i状态所需要的最少时间。

        转移:dp[ j | f [ i ] ] = min(dp[ j | f [ i ] ] , dp[ j ] + 1)。其中,j是暴力枚举所有状态,f[i]是两辆车所能单次运输的状态。

      最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
// int be[15];
int val[15];
int dp[10010];
int f1[1100];
int f2[1100];
int f[1100];
int cnt,n,c1,c2;
int getSum(int x)//计算一个状态所对应的代价
{
int ans=0;
int tot=0;
while(x>0)
{
tot++;
if(x&1) ans+=val[tot];
x>>=1;
}
return ans;
}
void before_hand()//预处理出两辆车单次运输所能运输的所有状态
{
// be[0]=1;
// for(int i=1;i<=10;i++)
// {
// be[i]=be[i-1]*2;
// }
int cnt1=0,cnt2=0;
for(int i=0;i<(1<<n);i++)
{
int k=getSum(i);
if(k<=c1) f1[++cnt1]=i;//f1表示第一辆车单次运输的状态
if(k<=c2) f2[++cnt2]=i;//f2表示第二辆车单次运输的状态
}
for(int i=1;i<=cnt1;i++)
{
for(int j=1;j<=cnt2;j++)
{
if(f1[i]&f2[j]) continue;
f[++cnt]=f1[i]|f2[j];
}
}
}
// bool v[10010];
// int minn=0x7f7f7f7f;
// void dfs(int temp,int s)
// {
// if(temp>minn) return;
// if(v[s]&&temp==minn) return;
// puts("Fuck");
// if(s==be[n]-1)
// {
// minn=min(minn,temp);
// return;
// }
// for(int i=1;i<=cnt;i++)
// {
// if(s&f[i]) continue;
// v[s^f[i]]=1;
// dfs(temp+1,s^f[i]);
// v[s^f[i]]=0;
// }
// }
void original()//初始化
{
memset(dp,0x3f,sizeof dp);
memset(f1,0,sizeof f1);
memset(f2,0,sizeof f2);
memset(f,0,sizeof f);
cnt=0;
}
int main()
{
int cases;
scanf("%d",&cases);
int base=0;
while(cases--)
{
original();//初始化
base++;
cin >> n >> c1 >> c2;
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
before_hand();
dp[0]=0;
for(int i=1;i<=cnt;i++)
{
for(int j=(1<<n)-1;j>=0;j--)//等号很重要,毕竟这不是不同的01背包
{
if(dp[j]==inf) continue;
if(j&f[i]) continue;
dp[j|f[i]]=min(dp[j|f[i]],dp[j]+1);//转移
}
}
printf("Scenario #%d:\n%d\n\n",base,dp[(1<<n)-1]);//输出即可... ...
}
return 0;
}
// int main()
// {
// cin >> n;
// for(int i=1;i<=n;i++)
// {
// scanf("%d",&val[i]);
// }
// printf("%d\n",getSum(17));
// return 0;
// }

    小结:在枚举状态压缩01背包时,不要将内层循环的0给排除。

      内存必须要开够

      poj不能将带有注释信息的代码直接上交,别问我是怎么知道的... ...

[poj2923]Relocation_状压dp_01背包的更多相关文章

  1. HDU 6125 Free from square (状压DP+背包)

    题意:问你从 1 - n 至多选 m 个数使得他们的乘积不能整除完全平方数. 析:首先不能整除完全平方数,那么选的数肯定不能是完全平方数,然后选择的数也不能相同的质因子. 对于1-500有的质因子至多 ...

  2. UVA - 10817 Headmaster's Headache (状压类背包dp+三进制编码)

    题目链接 题目大意:有S门课程,N名在职教师和M名求职者,每名在职教师或求职者都有自己能教的课程集合以及工资,要求花费尽量少的钱选择一些人,使得每门课程都有至少两人教.在职教师必须选. 可以把“每个课 ...

  3. POJ2923--Relocation(01背包+状压dp)

    果然对状压DP,我根本就不懂=.= /************************************************** Problem: 2923 User: G_lory Mem ...

  4. 树形DP和状压DP和背包DP

    树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...

  5. POJ 2923 【01背包+状态压缩/状压DP】

    题目链接 Emma and Eric are moving to their new house they bought after returning from their honeymoon. F ...

  6. POJ 3628 01背包 OR 状压

    思路: 1.01背包 先找到所有奶牛身高和与B的差. 然后做一次01背包即可 01背包的容积和价格就是奶牛们身高. 最后差值一减输出结果就大功告成啦! 2. 搜索 这思路很明了吧... 搜索的确可以过 ...

  7. NOI 2015 寿司晚宴 (状压DP+分组背包)

    题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...

  8. HDU 6125 Free from square (状压DP+分组背包)

    题目大意:让你在1~n中选择不多于k个数(n,k<=500),保证它们的乘积不能被平方数整除.求选择的方案数 因为质数的平方在500以内的只有8个,所以我们考虑状压 先找出在n以内所有平方数小于 ...

  9. NOIP模拟 乘积 - 状压dp + 分组背包

    题目大意: 给出n和k,求从小于等于n的数中取出不超过k个,其乘积是无平方因子数的方案数.无平方因子数:不能被质数的平方整除. 题目分析: 10(枚举\(n\le8\)),40(简单状压\(n\le1 ...

随机推荐

  1. javascript中的内存管理和垃圾回收

    前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...

  2. 资料--Linux开发

    <Linux/UNIX系统编程手册>凯利斯克 (Michael Kerrisk) <UNIX环境高级编程>(第2版),史蒂文斯著 <深入理解 Linux 内核>(第 ...

  3. webpacke踩坑-新手

    1.题叶-webpack入门指南 2.webpack入门系列 3.w3ctech的webpack入门及实践 4.Express结合Webpack的全栈自动刷新 5.webpack 单页面应用实战 6. ...

  4. 凸包--Graham扫描法

    一直听大佬们说:凸包.凸包.凸包 一直不会..... 然后.... 今天考试,考了一道计算几何的简单题.... 这,,,还是学一下吧.. 然后考试现场学习一下凸包算法. 先理解一下凸包是啥东西. 看看 ...

  5. $PkuWc\ 2018$ 酱油记

    PkuWc 2018 酱油记 1. Day -INF 又停了一个月课...... 感觉这个月的收获还是蛮大的,刚来的时候还只会线段树,到现在LCT都学了... 这个月不停在考试,自己考试技巧也提升了不 ...

  6. 【经验随笔】 Tomcat多个APP使用相同名称环境变量导致问题

    背景介绍 之前遇到一个问题,在一个tomcat下部署了两个APP,其中一个APP不能正常从底层接口获取数据.如果将两个APP分到不同服务器上的tomcat部署,又都正常了.分析了一下: 远程调试跟代码 ...

  7. Java的大数计算BigNumber

    Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, wit ...

  8. CSS之盒子模型(深入理解)

    CSS--盒子模型(Box Model) 简介: CSS盒子模型本质上是一个盒子,对网页中绝大部分的HTML元素进行包装定位(外边距,边框,内边距以及实际内容). 但是并不是所有的HTML元素都可以看 ...

  9. QT 5.9版本 使用MSVC2015编译时出现中文字符乱码问题的解决方法

    解决方法主要分为两种: 1.在项目->Project Settings ->编辑器 ->文件编码中使用System 2.对于中文字符,使用QString::fromLocal8Bit ...

  10. Mimikatz的使用心得

    Mimikatz是一款由法国人编写的轻量级调试工具,但更为人所知的是使用Mimikatz来获取Windows的明文密码. 这个软件的作者博客:http://blog.gentilkiwi.com/mi ...