POJ--2923--Relocation--状压DP

Relocation

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2288   Accepted: 950

Description

Emma and Eric are moving to their new house they bought after returning from their honeymoon. Fortunately, they have a few friends helping them relocate. To move the furniture, they only have two compact cars, which complicates everything a bit. Since the
furniture does not fit into the cars, Eric wants to put them on top of the cars. However, both cars only support a certain weight on their roof, so they will have to do several trips to transport everything. The schedule for the move is planed like this:

  1. At their old place, they will put furniture on both cars.
  2. Then, they will drive to their new place with the two cars and carry the furniture upstairs.
  3. Finally, everybody will return to their old place and the process continues until everything is moved to the new place.

Note, that the group is always staying together so that they can have more fun and nobody feels lonely. Since the distance between the houses is quite large, Eric wants to make as few trips as possible.

Given the weights wi of each individual piece of furniture and the capacities C1 and C2 of the two cars, how many trips to the new house does the party have to make to move all the furniture? If
a car has capacity C, the sum of the weights of all the furniture it loads for one trip can be at most C.

Input

The first line contains the number of scenarios. Each scenario consists of one line containing three numbers nC1 and C2C1 and C2 are the capacities of the cars (1
≤ Ci ≤ 100) and n is the number of pieces of furniture (1 ≤ n ≤ 10). The following line will contain n integers w1, …, wn, the weights of the furniture (1 ≤ wi ≤
100). It is guaranteed that each piece of furniture can be loaded by at least one of the two cars.

Output

The output for every scenario begins with a line containing “Scenario #i:”, where i is the number of the scenario starting at 1. Then print a single line with the number of trips to the new house they have to make to move
all the furniture. Terminate each scenario with a blank line.

Sample Input

2
6 12 13
3 9 13 3 10 11
7 1 100
1 2 33 50 50 67 98

Sample Output

Scenario #1:
2

Scenario #2:
3

题意:n个物品,两个车,车有自己的容量,物品有自己的体积,求最少的运送次数把物品全部运走,注意,两车一同发车。

解析:状态压缩DP,列举两车能够装下物品的所有方案,然后二进制找两车没有运相同物品的方案,然后用这些方案进行推算就出来了。

注意了,状态压缩就是用二进制的每一位来替代每个物品,所以n个物品的话最大就是n位

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Max (1<<15)
using namespace std;
int main (void)
{
    int t,n,c1,c2,i,j,k,l1,l2,L,cas=1;
    int s[11],dp[Max],s1[Max],s2[Max],dis[Max];
    scanf("%d",&t);
    while(t--&&scanf("%d%d%d",&n,&c1,&c2))
    {
        for(i=0;i<n;i++)
        scanf("%d",&s[i]);
        l1=l2=0;
        for(i=0;i<(1<<n);i++)	//演算所有可能方案
        {
            k=0;
            for(j=0;j<n;j++)	//拿这个方案计算出方案中所有物品的值的总和
            if(i&(1<<j))
            k+=s[j];
            if(k<=c1)s1[l1++]=i;	//总和小于c1车的容量表示这个方案可以用c1车来实现
            if(k<=c2)s2[l2++]=i;	//同上
        }
        L=0;
        for(i=0;i<l1;i++)	//一一对应比较
        for(j=0;j<l2;j++)
        if((s1[i]&s2[j])==0)	//与运算用来判断两个二进制数是否有某些位相同,即判断是否某些物品被两车都装了
        dis[L++]=(s1[i]|s2[j]);
        memset(dp,-1,sizeof(dp));
        dp[0]=0;	//基础方案初始化
        for(i=0;i<(1<<n);i++)	//遍历所有状态
        if(dp[i]>-1)	//预算的前提是这个基础点有值
        {
            for(j=0;j<L;j++)	//遍历所有方案
            {
                if((i&dis[j])==0&&(dp[i|dis[j]]==-1||dp[i|dis[j]]>dp[i]+1))//这里i&dis[j]==0是用来确定当前状态与当前方案没有冲突,冲突是指的当前状态已经用过某物品而这个方案正好要使用这个物品
                dp[i|dis[j]]=dp[i]+1;
            }
        }
        printf("Scenario #%d:\n%d\n\n",cas++,dp[(1<<n)-1]);//输出所有物品都被运送完了的状态中记录的值
    }
    return 0;
}

我觉得这个题很适用于状压DP的学习,我还刚接触,所以不会没有节操地大发厥词来写算法总结,嘎嘎嘎,先用两天再说。

时间: 2024-10-10 04:29:09

POJ--2923--Relocation--状压DP的相关文章

POJ 2923 Relocation(状压+背包)

Relocation Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2340   Accepted: 965 Description Emma and Eric are moving to their new house they bought after returning from their honeymoon. Fortunately, they have a few friends helping them r

POJ 2688 BFS+状压DP

标准的TSP问题 m*n矩阵,有不超过10个需要走到的点,给出起点,问走最少的步子把所有点走完 BFS出每个必须走到的点的最短距离 然后状压DP即可 #include "stdio.h" #include "string.h" #include "queue" using namespace std; const int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} }; int inf=0x7fffffff; in

POJ 3254 简单状压DP

没什么可说的,入门级状压DP,直接撸掉 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <map> #include <queue> #include <stac

Hie with the Pie(POJ 3311)状压DP

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be

poj 1185 (状压dp)

Problem 炮兵阵地 题目大意 给你一张n*m的地图,一些地区是空地,一些地区是障碍. 可以在空地上布置炮兵部队,炮兵部队的攻击范围为上下左右各两格. 询问最多可以布置多少个炮兵部队,且互不伤害. 0<=N <= 100 , 0<=M <= 10 解题分析 由于攻击范围是两格,所以用dp[i][j][k]表示做到i行,上一行的状态为j,上上行的状态为k. 判断上下两行的状态i,j是否矛盾,直接判断 i&j 是否为0即可. 判断同一行的状态i是否矛盾,用 i &

POJ 1185 经典状压dp

做了很久的题 有注释 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> using namespace std; int dp[107][107][107];///二维记录上一次 三维记录此次 ///dp[i][k][j]=max(dp[i][k][j],dp[i-1][t][k])+num[j]; t为枚举数且满足与 k

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

poj 1699 Best Sequence(AC自动机+状压DP)

题目链接:poj 1699 Best Sequence 题目大意:给定N个DNA序列,问说最少多长的字符串包含所有序列. 解题思路:AC自动机+状压DP,先对字符串构造AC自动机,然后在dp[s][i]表示匹配了s,移动到节点i时候的最短步数. #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <iostream> #include &

POJ 1185 炮兵阵地 状压dp

http://poj.org/problem?id=1185 经典题目不必多说,直接贴代码. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n, m, cnt, size; 7 int a[110], st[70], ct[70]; 8 char str[15]; 9 int f[110][70][70]; 10 void init(

POJ 3254 Corn Fields 状压DP

链接:http://poj.org/problem?id=3254 题意:一块M*N的田地,每小块地大小是1*1,可以种植物的标记为1,不可以种植物的标记为0,并且相邻的两块地不可以同时种植物.问题是有多少种不同的种植方案(所有地都不种也是一种种植方案) 思路:这是第一道状压DP题,从第一行更新到最后一行,每一行用一个N位的二进制数来表示该行的状态1表示该位置种了植物,0表示该位置没种植物.因为每块地只对相邻的土地能否种植有所影响,所以每一行的状态可以用前一行的状态递推得到. 资料:http:/