[POJ 2923] Relocation (动态规划 状态压缩)

题目链接:http://poj.org/problem?id=2923

题目的大概意思是,有两辆车a和b,a车的最大承重为A,b车的最大承重为B。有n个家具需要从一个地方搬运到另一个地方,两辆车同时开,问最少需要搬运几次?

我先想的是我由A车开始搬,搬运能装的最大的家具总重,然后状态压缩记录下搬运了哪些,然后再由B车搬运,状态压缩记录搬运了哪些。以此类推,直到状态满了。

以上方法TLE

然后,实在想不出来了,看了题解:http://blog.csdn.net/woshi250hua/article/details/7636061

也就是说先确定哪些状态是两辆车一次可以搬完的。

怎么确定呢?首先我们先确定出给定状态集合中所有可能出现的并且可以被a车运送的重量,然后看是否存在总重量减去可被a车运送的重量所得到的剩余重量是否能够被b车运送。

如果可以,则这个状态是可以被a,b两辆车一次就送完的。

那么怎么确定给定状态集合中所有可能出现的并且可以被a车运送的重量呢?

这又是一个dp。

设计状态dp[i][j]表示状态集合中的前i个物品是否能够组成j这个重量

如果dp[i-1][j-w[i]]已经出现了(就是说如果存在了重量j-w[i],我只需要填上重量w[i]就可以形成j),那么dp[i-1][j]就可以组成。

这个问题结束。

对于总问题:

设计状态dp[i][j]表示从前i种已知可以一次搬完的里面搬状态j需要的最少次数。

状态转移:dp[i][j|mask[i]] = min(dp[i-1][j]+1,dp[i-1][j|mask[i]])

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <map>
 6 #include <iterator>
 7 #include <vector>
 8 using namespace std;
 9 typedef long long LL;
10
11 int T;
12 int n,c[2];
13 int w[22];
14 int mask[2222];
15 int dp[2222];
16
17 bool C(int x){
18     bool can[110];
19     memset(can,0,sizeof(can));
20     can[0] = true;
21     int sum = 0;
22     for( int i=1;i<=n;i++ )if((x>>(i-1))&1){
23         sum += w[i];
24         for( int j=c[0];j>=w[i];j--){
25             if( can[j-w[i]] ) can[j] = true;
26         }
27     }
28     for(int i=0;i<=c[0];i++){
29         if( can[i]&&sum-i<=c[1] ) return true;
30     }
31     return false;
32 }
33
34 int main(){
35     scanf("%d",&T);
36     for(int t=1;t<=T;t++){
37         scanf("%d%d%d",&n,&c[0],&c[1]);
38         for(int i=1;i<=n;i++) scanf("%d",&w[i]);
39         int ptr = 0;
40         for(int i=1;i<(1<<n);i++){
41             if( C(i) ) mask[++ptr] = i;
42         }
43         const int INF = 9999;
44         fill(dp,dp+2222,INF);
45         dp[0] = 0;
46         for(int i=1;i<=ptr;i++){
47             for(int j=(1<<n)-1;j>=0;j--) if((mask[i]&j)==0) {
48                 dp[mask[i]|j] = min(dp[mask[i]|j],dp[j]+1);
49             }
50         }
51         printf("Scenario #%d:\n%d\n\n",t,dp[(1<<n)-1]);
52     }
53     return 0;
54 }

代码

时间: 2024-08-05 19:37:30

[POJ 2923] Relocation (动态规划 状态压缩)的相关文章

poj 2923 Relocation 解题报告

题目链接:http://poj.org/problem?id=2923 题目意思:给出两部卡车能装的最大容量,还有n件物品的分别的weight.问以最优方式装入,最少能运送的次数是多少. 二进制表示物品状态:0表示没运走,1表示已被运走. 枚举出两辆车一趟可以运出的状态.由于物品是一趟一趟运出来的.所以就可以由一个状态通过两辆车一趟的状态转移到另一个状态. dp[i]=MIN(dp[k]+1).k可以由两车一趟转移到i. 我是参考此人的:http://blog.csdn.net/bossup/a

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3254 Corn Fields 状态压缩DP

题目链接:http://poj.org/problem?id=3254 思路:状态压缩DP,状态方程为dp[i][j] += (dp[i-1][k]) code: #include <stdio.h> #include <string.h> #define N 500 const int MOD = 100000000; int dp[15][N],ant[N],n,m,k,map[15]; bool ok(int x) { if(x&(x<<1))return

POJ 3691 (AC自动机+状态压缩DP)

题目链接:  http://poj.org/problem?id=3691 题目大意:给定N的致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题思路: 首先说一下AC自动机在本题中的作用. ①字典树部分:负责判断当前0~i个字符组成的串是否包含致病DNA,这部分靠字典树上的cnt标记完成. ②匹配部分:主要依赖于匹配和失配转移关系的计算,这部分非常重要,用来构建不同字符间状态压缩的转移关系(代替反人类的位运算). 这也是必须使用AC自动机而

POJ 3254. Corn Fields 状态压缩DP (入门级)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

POJ 1753 Flip game状态压缩+广搜

题意有4*4的16个方格,每个方格有黑白两种颜色,每次点击方格后,被点击方格本身及其上下左右的方格都会改变颜色.给出一组状态,求将这组状态变为全白或者全黑至少需要点击几次.若无法达到,则输出Impossible. 样例输入bwwbbbwbbwwbbwww 样例输出4 思路每个方格只有黑白两种颜色,且只有16个方格,因此可以把每个状态看作一个16位的二进制数(状态压缩),2^16=25536,因此可以用int来保存状态.然后就是BFS暴搜,直到状态为0或者65535(全1)为止. 注意点65535

ACM学习历程—HDU1584 蜘蛛牌(动态规划 &amp;&amp; 状态压缩)

Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离. Input 第一个输入数据是T,表示数据的组数.

POJ 3254 Corn Fields(状态压缩DP)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

[ACM] POJ 3254 Corn Fields(状态压缩)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8062   Accepted: 4295 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm