http://poj.org/problem?id=2923
poj 2923 Relocation
首先dfs出两辆车可一次运走的货物的所有组合情况,再用bfs找到最优解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1050;
int n, w[15], value, c1, c2, cnt, bn[15], st[maxn*2], dp[maxn*2];
void dfs( int id, int st1, int st2, int w1, int w2){
for(int i= id+ 1; i<= n; i++){
if( (st1 & bn[i]) == 0 && (st2 & bn[i]) == 0){
if( w[i] + w1 <= c1 ){
st[st1|bn[i]|st2] = 1;
dfs(i, (st1 | bn[i]), st2, w1+ w[i], w2);
}
if( w[i] + w2 <= c2){
st[st2|bn[i]|st1] = 1;
dfs(i, st1, (st2 | bn[i]), w1, w2 + w[i]);
}
}
}
}
int bfs(){
int i, j, k, tt, tmp;
queue<int > q;
memset( dp, -1, sizeof( dp));
q.push(0);
dp[0] = 0;
while( !q.empty()){
j = q.front();
if( j == value) break;
q.pop();
for( k = 0; k<= value; k++){
if( (j&k) != 0 )continue;
if( st[k] == -1) continue;
if( dp[j|k] != -1) continue;
dp[j|k] = dp[j] + 1;
q.push(j|k);
}
}
return dp[value];
}
int main(){
//freopen("1.txt", "r", stdin);
int i, j, k, cas= 1, T, mm, cc, tans, tmp;
for( i= 0; i<= 11; i++){
bn[i] = (1<<i);
}
scanf("%d", &T);
while( T-- ){
scanf("%d%d%d", &n, &c1, &c2);
value= 0;
for( i= 1; i<=n; i++)
value|= bn[i];
for( i= 1, tans= 0, tmp = 0; i<= n; i++){
scanf("%d", &w[i]);
tans+= w[i];
}
if( tans == 0){
printf("Scenario #%d:\n0\n\n", cas++, mm);
continue;
}
sort(w+1, w+1+n);
memset( st, -1, sizeof( st));
dfs(0, 0, 0, 0, 0);
mm = bfs();
printf("Scenario #%d:\n%d\n\n", cas++, mm);
}
return 0;
}