POJ 2923 状压好题

Relocation

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2631   Accepted: 1075

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

Source

TUD Programming Contest 2006, Darmstadt, Germany

题目意思:

有两辆容量分别为c1和c2的车,有n个体积为v[i]的物品,现用车拉物品,最少用多少次把所有物品拉完。

思路:

状压物品,记录所有可以一次性拉的物品组合二进制状态,那么答案肯定是由这些记录过的状态组合而成的,dp即可。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <queue>
 7 #include <cmath>
 8 #include <set>
 9 using namespace std;
10
11 #define N 100005
12 #define inf 999999999
13
14 int n, c1, c2;
15 int w[15];
16 int num[1050];
17
18 bool solve(int nn){
19     int i, j, k;
20     int sum=0;
21     bool visited[105];
22     memset(visited,false,sizeof(visited));
23     visited[0]=true;
24     for(i=0;i<n;i++){
25         if((1<<i)&nn){
26             sum+=w[i];
27             for(j=c1-w[i];j>=0;j--){//DP
28                 if(visited[j])
29                     visited[j+w[i]]=true;
30             }
31         }
32     }
33     for(i=0;i<=c1;i++){
34         if(visited[i]&&sum-i<=c2)
35             return true;
36     }
37     return false;
38 }
39
40
41 main()
42 {
43     int t, i, j, k;
44     int kase=1;
45     cin>>t;
46     while(t--){
47         scanf("%d %d %d",&n,&c1,&c2);
48         for(i=0;i<n;i++) scanf("%d",&w[i]);
49         int len=0;
50         int cnt=(1<<n)-1;
51         for(i=0;i<=cnt;i++){
52             if(solve(i))
53                 num[len++]=i;
54         }
55         int dp[1050];
56         for(i=0;i<=cnt;i++) dp[i]=inf;
57         dp[0]=0;
58         for(i=0;i<len;i++){//DP
59             for(j=cnt;j>=0;j--){
60                 if(!(j&num[i])){
61                     dp[j|num[i]]=min(dp[j|num[i]],dp[j]+1);
62                 }
63             }
64         }
65         printf("Scenario #%d:\n%d\n\n",kase++,dp[cnt]);
66     }
67 }
时间: 2024-10-11 14:27:22

POJ 2923 状压好题的相关文章

poj 2923 状压dp+01背包

好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态集合里的那些物品能否一次就运走,如果能运走,那就把这个状态看成一个物品.预处理完能从枚举中找到tot个物品,再用这tol个物品中没有交集(也就是两个状态不能同时含有一个物品)的物品进行01背包,每个物品的体积是state[i],价值是1,求包含n个物品的最少价值也就是dp[(1<<n)-1](dp

POJ 1038 状压DP

一个公司生产一种2*3规模的芯片,但是原材料上面有一些地方是不能用来当作芯片材料的,给出原料大小,及上面不能做原料的点,问你怎么分解,可以使生成芯片最大化. 对M进行三进制状压 last数组存储第i-1行和i-2行状态,cur数组存储i行和i-1行状态 cur[k]=2; // 本行k位置和上行k位置都不可用 cur[k]=1; // 本行k位置可用,上行k位置不可用 cur[k]=0; // 本行和上行位置k均可用 必须用滚动数组,否则爆内存 #include "stdio.h" #

Best Sequence(poj 1699) 状压dp(TSP)

类似于前两天做的那个wordstack.状压的其实有时候爆搜+记忆化也差不多. 就是这个是要与之前的都重合,移位预处理要注意. 理解好第一个样例就行 /* *********************************************** Author :bingone Created Time :2014/12/9 22:48:56 File Name :a.cpp ************************************************ */ #inclu

POJ 3254 状压DP

题目大意: 一个农民有一片n行m列 的农场   n和m 范围[1,12]  对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. 告诉你 n ,m 和那些地方能种菜哪些地方不能种菜,求农夫一共有多少种方案种菜 解法: 基本思想是状压 也就是用一个int 型的数代表一行的种菜策略,二进制的0代表该位不能种菜,1位代表能种菜,使用位运算使处理速度变快 对于单行行,最多有2^12 种情况,并且 2^12种情况里面还有很多不满足题意的

POJ 2411 状压DP经典

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

POJ 2686(状压DP

第一次做状压感觉那一长串for显示了这是个多么暴力的算法呢...1A了倒是挺顺的 #include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<utility> #include<vector> #include<cstring> #include<cmath> #define INF 0x3fffffff #d

POJ 2777 状压线段树

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36586   Accepted: 11041 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

POJ 3254 (状压DP) Corn Fields

基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << 1) 非0,说明有相邻的两个1 判断一个状态能否放在该行: 如果 (a[i] & state) != state,说明是不能放置的.因为a[i]中存在某个0和对应state中的1,与运算之后改变了state的值 判断相邻两行的状态是否有同一列相邻的1: 如果(state & _state)不

状压DP题集

[状压DP]Codeforces - 580D Kefa and Dishes (状压DP+记忆化搜索)(经典) 题目大意: 有$n ( n \leq18 )$个菜,现在要挑选$m$道菜,每个菜有一个满意度$a_i$,还有$k$个关系,每个关系为 $a b c$,表示$a$在$b$之前吃的话,就会额外增加$c$的满意度,现在要你输出最大的满意度. 解题分析:$n$的数据范围很小,很容易想到状压DP. #include <bits/stdc++.h> using namespace std; #