ZOJ_3620 Escape Time II

来源:互联网 发布:淘宝代运营如何收费 编辑:程序博客网 时间:2024/06/06 04:32

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3620

题意:

有N个房间,每个房间都有一定的珠宝量,给你T秒钟,从起点s出发,问如果要求在t之前

要达到终点e你最多能拿多少珠宝。

思路:

本题的N<=10,可以直接枚举每种状态,然后进行一次dp就可以了。

#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>const int inf = 0x3fffffff ;int n , m , t ;int s, e , S;int val[15] ;int map[13][13] ;int dp[13][1<<10] ;std::vector< std::pair<int,int> > v ;bool comp( std::pair<int , int > p1,  std::pair<int , int>p2 ){    return p1.first > p2.first ;}bool solve(){    for(int k=0;k<n;k++){        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                if( map[i][k]!=inf && map[k][j]!=inf && map[i][j] > map[i][k] + map[k][j] )                    map[i][j] = map[i][k] + map[k][j] ;            }        }    }    if( map[s][e] == inf )  return false ;    std::sort(v.begin() , v.end() , comp ) ;    return true ;}bool is_ok(int b){    if( (b&(1<<s))!=0 && (b&(1<<e))!=0 )    return true ;        return false ;}bool is_single(int a){    int b = a & (a - 1 ) ;    if(b == 0)  return 1 ;    else        return 0;}int DP(int i , int j){    if( dp[i][j]!=-1 )  return dp[i][j];    if( is_single(j) ){        if( i == s )            dp[i][j] = 0 ;        else    dp[i][j] = inf ;        return dp[i][j] ;    }    int jj = j ^ (1<<i) ;    int _min = inf ;    for(int ii=0;ii<n;ii++){        if( (jj&(1<<ii)) !=0 ){            if( DP(ii , jj)!= inf  && map[ii][i]!=inf && DP(ii,jj)+map[ii][i] < _min)                _min = DP(ii, jj) + map[ii][i] ;        }    }    dp[i][j] = _min ;    return dp[i][j] ;}int get_ans(int b){    memset(dp,  -1 , sizeof(dp));    return DP(e ,b);}void DP(){    for(int i=0;i<v.size();i++){        int a = v[i].first , b = v[i].second ;        if( is_ok(b) ){            if( t>=get_ans( b ) ){                printf("%d\n",a) ;  return ;            }        }    }    printf("0\n");  return ;}int main(){    int a,b ,c ;    while( scanf("%d%d%d",&n,&m,&t) == 3){        scanf("%d %d",&s,&e);        for(int i=0;i<n;i++)   scanf("%d",val+i);        S = 1 << n ;        v.clear() ;        for(int j=1;j<S;j++){            int a = 0 ;            for(int i=0;i<n;i++){                if( (j&(1<<i)) != 0 ){                    a += val[i] ;                }            }            v.push_back( std::make_pair(a ,j) );        }        for(int i=0;i<n;i++){            for(int j=0;j<n;j++)                map[i][j] = inf ;            map[i][i] = 0 ;        }        for(int i=0;i<m;i++){            scanf("%d %d %d",&a,&b,&c) ;            if(c < map[a][b] )  map[a][b] = map[b][a] = c ;        }        if( !solve() ){            printf("0\n");  continue ;        }        DP() ;    }    return 0;}


原创粉丝点击