poj 2923 Relocation 二進制狀態壓縮 深搜+廣搜

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;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章