[poj2923]Relocation_状压dp_01背包
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背包的更多相关文章
- HDU 6125 Free from square (状压DP+背包)
题意:问你从 1 - n 至多选 m 个数使得他们的乘积不能整除完全平方数. 析:首先不能整除完全平方数,那么选的数肯定不能是完全平方数,然后选择的数也不能相同的质因子. 对于1-500有的质因子至多 ...
- UVA - 10817 Headmaster's Headache (状压类背包dp+三进制编码)
题目链接 题目大意:有S门课程,N名在职教师和M名求职者,每名在职教师或求职者都有自己能教的课程集合以及工资,要求花费尽量少的钱选择一些人,使得每门课程都有至少两人教.在职教师必须选. 可以把“每个课 ...
- POJ2923--Relocation(01背包+状压dp)
果然对状压DP,我根本就不懂=.= /************************************************** Problem: 2923 User: G_lory Mem ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- POJ 2923 【01背包+状态压缩/状压DP】
题目链接 Emma and Eric are moving to their new house they bought after returning from their honeymoon. F ...
- POJ 3628 01背包 OR 状压
思路: 1.01背包 先找到所有奶牛身高和与B的差. 然后做一次01背包即可 01背包的容积和价格就是奶牛们身高. 最后差值一减输出结果就大功告成啦! 2. 搜索 这思路很明了吧... 搜索的确可以过 ...
- NOI 2015 寿司晚宴 (状压DP+分组背包)
题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...
- HDU 6125 Free from square (状压DP+分组背包)
题目大意:让你在1~n中选择不多于k个数(n,k<=500),保证它们的乘积不能被平方数整除.求选择的方案数 因为质数的平方在500以内的只有8个,所以我们考虑状压 先找出在n以内所有平方数小于 ...
- NOIP模拟 乘积 - 状压dp + 分组背包
题目大意: 给出n和k,求从小于等于n的数中取出不超过k个,其乘积是无平方因子数的方案数.无平方因子数:不能被质数的平方整除. 题目分析: 10(枚举\(n\le8\)),40(简单状压\(n\le1 ...
随机推荐
- 嵌入式linux------SDL移植(am335x下显示bmp图片)
#include<stdio.h> #include "/usr/local/ffmpeg_arm/include/SDL/SDL.h" char *bmp_name[ ...
- ORA-00904:标识符无效
1.错误描述 ORA-00904:"TTT"."RN":标识符无效 00904 . 00000 - "%s:invalid identifier&qu ...
- Monkeyscript---获取包名主界面名和位置坐标
一.monkey随机事件有三类:点击.输入.手势 二.Monkeyscript难点:如何获取坐标 三.Monkeyscript API: 1.轨迹球(手势)事件: DispatchTrackball( ...
- Asp.Net WebApi 调试利器“单元测试”
当我们编辑好一个WebApi应用程序后,需要对该Api接口进行调试,传统的调试办法是在方法内设置断点,然后用PostMan等http工具模拟访问进行查看WebAPI的运行情况,但这种除了效率较低还进行 ...
- [BZOJ1058][ZJOJ2007]报表统计
BZOJ Luogu 题目描述 Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观察,小Q发现统计一张报表实际上是维 ...
- MSIL实用指南-IL版hello world
我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...
- 性能测试-并发和QPS
性能测试-并发和QPS 响应时间: cpu计算耗时 + cpu等待耗时 + 网络io耗时 + 磁盘io耗时 并发: 服务端并发和客户端并发不是同一个概念.客户端并发仅仅是为了模拟多用户访问,服务端并发 ...
- 去除IE10自带的清除按钮
最近在工作中碰到了一个问题,原本在IE8,IE9下正常的input表单,在IE10下会出现清除按钮,即表单右侧会出现一个可以清除该表单内容的小叉.由于之前一直没有兼容过IE10,所以我专门搜了下原因. ...
- JDK配置及tomcat部署
JDK配置及tomcat部署 2017-09-30-17:54:03 个人原创博客,转载请注明出处,作者,否则依法追究责任,文中引用了一些百度经验的图片,特此注明. 一,配置JDK:1.8.0_66版 ...
- c语言基础知识
进制: l 碾(nian)除法:十进制转为几进制则除几,从下往上看余数 (十进制转二进制,十进制转八进制,十进制转十六进制) l 几进制转化为十进制:直接乘以几的次方数: l binary: ...