POJ 2923 Relocation(01背包+状态压缩)
题意:有人要搬家,有两辆车可以运送,有若干家具,车有容量限制,而家具也有体积,那么如何运送会使得运送车次最少?规定两车必须一起走,两车一次来回只算1躺。
思路:家具怎么挑的问题,每趟车有两种可能:1带走此家具;2此趟暂时不带走。那就是01背包了。但是限制是两只车的容量。求的是趟数。
1)数据量较小,将这10件以内的所有物品的可能组合记录一下,有2^10种,其中是包含了一些运不走的组合,滤掉,只留下可能的组合。对每种可能的新组合进行01背包,即考虑对于新组合i这种运送方案该不该取,如果取了能使车次更少,那就取。那就得穷举除了i所组合的物品外的所有可能的组合,所要决策的是 “该组合与i组合”后有没有可能减少车次,没有的话不更新了,按老方案。
#include <iostream>
#include <cstring>
#include <cstdio>
#define INF 0x1fffffff
using namespace std;
const int N=;
int n,car1,car2;
int w[N];
int tmp_dp[<<N];
int pre[<<N];
int dp[<<N]; int can_take(const int j)
{
int sum=;
memset(tmp_dp,,sizeof(tmp_dp));
for(int i=; i<n; i++)
{
if( (<<i)&j )
{
sum+=w[i];
if(car1+car2<sum)
return ;
for(int k=car1; k>=w[i]; k-- )//对其中一只车进行01背包
tmp_dp[k]=max(tmp_dp[k], tmp_dp[k-w[i]]+w[i]);
}
}
if(sum-tmp_dp[car1]>car2) return ;
return ;
} int cal()
{
memset(pre,,sizeof(pre));
int ful=(<<n)-, len=;
for(int i=ful; i>; i-- ) //预处理
if( can_take(i) )
pre[len++]=i;
int sta=;
dp[]=;
for(int i = ; i<=ful; i++) dp[i] = INF; //初始化 for(int i=; i<len; i++) //每个组合品
{
for(int j=ful-pre[i]; j>=; j--) //扣除i这几种物品,穷举其他所有的组合品(包括空组合),看是否与组合品i组合会使用更少的次数。如果原来已经有方案运走包括组合品i与其他一些组合的车次更少,那么不考虑运送组合品i(因为i组合得不合理)。
{
if( !(j&pre[i])) //j和组合品i无交集,在原来的方案j上考虑第i个放不放,若放就将车次+1。如果放,则要更新的应该是j|pre[i]这个放了i组合品的状态。
{
dp[j|pre[i]]=min(dp[j]+, dp[j|pre[i]]); //(放, 不放)
}
}
}
return dp[ful];
} int main() {
freopen("input.txt", "r", stdin);
int t, e=;
cin>>t;
while(t--)
{
scanf("%d %d %d", &n, &car1, &car2);
for(int i=; i<n; i++) scanf("%d", &w[i]);
printf("Scenario #%d:\n%d\n\n", ++e, cal());
}
return ;
}
AC代码
2) WA思路:对所有可能运走的组合计算其最大运送量并记录其状态,每步从中找出不与之前相交的最大运送量,看几趟之后能全送走。贪心的思想,每步择运送量最大的,只要维持没有交集就行了,最后肯定全都送走。过了样例,过不了poj的数据。难道还有一种运法:每一趟不是最佳,但是和下一趟组合起来就是最佳?比如有两趟的方案100+60,但也有方案80+70,这样就变成每趟非最佳,但是总方案却是最佳。MYBE!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=;
int n,car1,car2;
int w[N];
int tmp_dp[<<N];
int pre[<<N]; int can_take(const int j)
{
int sum=;
memset(tmp_dp,,sizeof(tmp_dp));
for(int i=; i<n; i++)
{
if( (<<i)&j )
{
sum+=w[i];
if(car1+car2<sum)
return ;
for(int k=car1; k>=w[i]; k-- )
tmp_dp[k]=max(tmp_dp[k], tmp_dp[k-w[i]]+w[i]);
}
}
if(sum-tmp_dp[car1]>car2) return ;
return sum;
} int cal()
{
memset(pre,,sizeof(pre));
int ful=(<<n)-, len=; for(int i=ful; i>; i-- ) //预处理:pre[i]表示i这种组合的家具价值
pre[i]=can_take(i); int sta=;
for(int i=; i<n; i++) //最多n趟
{
int v=,s=;
for(int j=ful; j>=; j--) //扫描除了sta的所有组合,挑出运送量最大的。
{
if(!(j&sta)) //无交集
{
if(pre[j]>v)
{
v=pre[j];
s=j;
}
}
}
sta|=s;
if((sta&ful)==ful) //如果已经运完
return i+;
}
return n;
} int main() {
//freopen("input.txt", "r", stdin);
int t, e=;
cin>>t;
while(t--)
{
scanf("%d %d %d", &n, &car1, &car2);
for(int i=; i<n; i++) scanf("%d", &w[i]); printf("Scenario #%d:\n%d\n\n", ++e, cal());
}
return ;
}
WA代码
POJ 2923 Relocation(01背包+状态压缩)的更多相关文章
- POJ 2923 【01背包+状态压缩/状压DP】
题目链接 Emma and Eric are moving to their new house they bought after returning from their honeymoon. F ...
- POJ 2923 Relocation(01背包变形, 状态压缩DP)
Q: 如何判断几件物品能否被 2 辆车一次拉走? A: DP 问题. 先 dp 求解第一辆车能够装下的最大的重量, 然后计算剩下的重量之和是否小于第二辆车的 capacity, 若小于, 这 OK. ...
- hdu6149 Valley Numer II 分组背包+状态压缩
/** 题目:hdu6149 Valley Numer II 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意: 众所周知,度度熊非常喜欢图. ...
- hdu6125 Free from square 分组背包+状态压缩
/** 题目:hdu6125 Free from square 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6125 题意: 从不大于n的所有正整数中选出 ...
- poj - 3254 - Corn Fields (状态压缩)
poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...
- POJ 2923 Relocation (状态压缩,01背包)
题意:有n个(n<=10)物品,两辆车,装载量为c1和c2,每次两辆车可以运一些物品,一起走.但每辆车物品的总重量不能超过该车的容量.问最少要几次运完. 思路:由于n较小,可以用状态压缩来求解. ...
- POJ 2923 Relocation 装车问题 【状态压缩DP】+【01背包】
题目链接:https://vjudge.net/contest/103424#problem/I 转载于:>>>大牛博客 题目大意: 有 n 个货物,并且知道了每个货物的重量,每次用 ...
- [POJ 2923] Relocation (动态规划 状态压缩)
题目链接:http://poj.org/problem?id=2923 题目的大概意思是,有两辆车a和b,a车的最大承重为A,b车的最大承重为B.有n个家具需要从一个地方搬运到另一个地方,两辆车同时开 ...
- POJ-2923 Relocation---01背包+状态压缩
题目链接: https://vjudge.net/problem/POJ-2923 题目大意: 有n个货物,给出每个货物的重量,每次用容量为c1,c2的火车运输,问最少需要运送多少次可以将货物运完 思 ...
随机推荐
- 7.20实习培训日志-Java基础程序设计结构
Java基础程序设计结构 在 Math 类中,为了达到最快的性能,所有的方法都使用计算机浮点单元中的例程,如果得到一个完全可预测的结果比运行速度更重要的话,那么就应该使用StrictMath类,它使用 ...
- Newtonsoft.Json序列化字符串-格式化和时间格式问题
最近C#中需要将实体进行json序列化,使用了Newtonsoft.Json public static void TestJson() { DataTable d ...
- tcpkill工作原理分析
此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 日常工作生活中大家在维护自己的服务器.VPS有时会碰到这样的情况:服务器上突然出现了许多来自未知ip的网络连 ...
- 杭电1003_Max Sum
这是原题的链接http://acm.hdu.edu.cn/showproblem.php?pid=1003 起初我是利用暴力的方法,求出所有序列的和的情况,每取一个序列就和以知道的最大和作对比,取大者 ...
- uva1626 Brackets sequence
题目大意: 给一个有小括号和中括号组成的序列,满足题中的三个条件时,是合法的.不满足时是不合法的,问将一个不合法的序列最少添加几个括号可以使之变成合法的.输出最短合法序列. /* 比较坑的一道题,wa ...
- css清除浮动的方法总结
在各种浏览器中显示效果也有可能不相同,这样让清除浮动更难了,下面总结8种清除浮动的方法,测试已通过 ie chrome firefox opera,需要的朋友可以参考下 清除浮动是每一个 we ...
- jsp学习与提高(三)——JSP Cookie 处理
1.cookie是什么 Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookie的支持. 通常有三个步骤来识别回头客: 服务 ...
- Luogu P4403 [BJWC2008]秦腾与教学评估【二分答案】By cellur925
题目传送门 这道题:真·凉心出题人. 二分答案,个人感觉其实并不只适用于有明显的"最大值最小/最小值最大"条件的题目,其实也可以称它为一种"优化的暴力".这题就 ...
- CF 1215解题报告
T1 偶数输出n/2 奇数输出(n-1)/2即可 T2 判断是不是回文 不是直接输出子串 是回文继续判断 如果他前(len+1)/2内没有相同 输出-1 其他的 交换不同字符,输出子串 T3 贪心+二 ...
- 送气球.jpg(模拟)
链接:https://ac.nowcoder.com/acm/contest/318/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...