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