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 一些关于css操作的函数

    // 通过样式表 获得css样式 //obj 表示dom对象,name 表示css属性 比如width等 function getStyle(obj,name){ if(obj.currentStyl ...

  2. thinphp 整合ueditor

    我的ueditor是部署在public/editor 部署前台页面 <script type="text/javascript" > var UEDITOR_HOME_ ...

  3. 引导加载程序之争: LILO 和 GRUB

    在不考虑他们的工作或专业情况下,所有 Linux 用户都会使用的是哪个工具?引导加载程序.通过本文了解引导加载程序的工作原理,认识两个流行的引导加载程序 LILO(LInux LOader)和 GNU ...

  4. Android线程间通信机制——深入理解 Looper、Handler、Message

    在Android中,经常使用Handler来实现线程间通信,必然要理解Looper , Handler , Message和MessageQueue的使用和原理,下面说一下Looper , Handl ...

  5. html->html5->css->javascript(js)->jQuery->AJAX->JSON

    首先来讲HTML,html是很多人接触到的第一种编写网页的语言,小编是在大学本科期间的编程课程上接触到html的,小小的几行代码就能编制出精彩绝伦的网页,不禁令人赞叹!HTML的语法自然不用多说,网上 ...

  6. Django学习-9-ORM多对多操作

    创建多对多:             方式一:自定义关系表                 class Host(models.Model):                     nid = mo ...

  7. WPF基础篇之资源文件路径

    WPF资源文件的路径 关于WPF资源文件的路径 这几天在WPF中调用资源文件的Uri时,因为是在代码里调用Uri写的Uri总是不对,要么运行直接报异常,要么说找不到资源文件.下面是我解决的整个经过和碰 ...

  8. Xampp apache与mySQL开不了 解决办法

    Xampp安装后,打开Xampp control panel. 点击Apache对应的Start,开不了.原因是系统的服务占用了80端口,所以要么结束系统服务,要么修改apache端口. 个人比较喜欢 ...

  9. jquery的各种插件调用(有些已经过时,以备注,其他的一些可以闲的时候用作拆解)

    jquery的valiteDate验证插件应用 <!DOCTYPE html> <html>        < head>            < meta ...

  10. 禁ping以及清理系统多余账号说明

    查出多余的:grep -v “nologin$“ /etc/passwd