/*
* 狀態壓縮+01背包
* 題意為:給你2個卡車的承載量和一些物品的重量,要求使用卡車將物品從一個地方運送到另一個地方
* 并且要求運送的次數最少
* 題解:由於物品的數量(1<=n<=10),使用二進制的思想枚舉出所有可能,也就是每個物品的組合狀態
* 對於每個狀態下的物品,枚舉出所有組合的可能,并且判斷是否能讓car1和car2一次運送,若能,則記錄下來
* 然後狀態:dp[i] 表示i狀態下最少的運送次數
* 狀態轉移方程: dp[i] = min(dp[i|j], dp[j]+1);
* 其中i|j是兩個狀態的結合,如果等式i+j == i|j,表示兩個集合沒有交集,可以進行狀態轉移
* 最後ans = dp[(1<<n)-1]
* State compression +01 backpack
* The meaning of the questions is: give you two trucks carrying amount and weight of some items, require the use of trucks to transport goods from one place to another place
* And require the conveyance of the least number of
* Problem solution: all the possible, that is, the combined state of the each of the articles due to the number of items (1 <= n <= 10), the idea of using a binary enumeration
* Items for each state, enumerate all the possible combinations, and judge whether to allow car1 and car2 transportation, if the record
* Then the state: dp [i] i state minimum delivery times
* State transfer equation: dp [i] = min (dp [i | j], dp [j] + 1);
* I | j is the combination of the two states, if the equation i + j == i | j, two sets intersection of state transfer
* The last ans = dp [(1 << n) -1]
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN (1<<11)
#define INF 0x3f3f3f3f
int n, v1, v2;
int dp[MAXN], used[MAXN], rs[MAXN], cost[MAXN];
bool can_relocation(int x)
{
int sum(0);
memset(used, 0, sizeof(used));
used[0] = 1;
for(int i = 0; i < n; i ++) {
if( (1<<i)&x ) {
sum += cost[i];
for(int j = v1; j >= cost[i]; j --) {
if( used[j-cost[i]] ) {
used[j] = 1;
}
}
}
}
for(int i = 0; i <= v1; i ++) {
if( used[i] && ((sum-i) <= v2) ) {
return true;
}
}
return false;
}
int dynamic(void)
{
int rs_pos(0), t_pos;
fill(dp, dp+MAXN, INF);
dp[0] = 0;
for(int i = 0; i < (1<<n); i ++) {
if( true == can_relocation(i) ) {
rs[rs_pos ++] = i;
}
}
for(int i = 0; i < rs_pos; i ++) {
for(int j = (1<<n)-1; j >= 0; j --) {
t_pos = j+rs[i];
if( t_pos != (j | rs[i]) ) {
continue;
}
dp[t_pos] = min(dp[t_pos], dp[j]+1);
}
}
return dp[(1<<n)-1];
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int cnt(1), cas;
scanf("%d", &cas);
while( cas -- ) {
scanf("%d %d %d", &n, &v1, &v2);
for(int i = 0; i < n; i ++) {
scanf("%d", &cost[i]);
}
printf("Scenario #%d:\n%d\n\n", cnt ++, dynamic());
}
return 0;
}
poj_2923
最新推荐文章于 2022-06-22 15:04:51 发布