题目说要在规定时间内,拿走最大价值。因为房间n <= 10 太小了,所以直接枚举 走过哪几个房间,然后dp 递推下去就可以了
dp[i][j] 走过i状态的房间,现在在第j个房间上面花费的最小时间。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define N 12 8 #define M 110 9 #define inf 1000000000 10 typedef long long LL; 11 int v[N], val[1<<N]; 12 struct node { 13 int v, next, l; 14 }e[M]; 15 int mpp[N][N], dp[1<<N][N]; 16 int main() { 17 int n, m, t, s, e; 18 while (scanf("%d%d%d", &n, &m, &t) != EOF) { 19 scanf("%d%d", &s, &e); 20 for (int i = 0; i < n; ++i) { 21 scanf("%d", &v[i]); 22 for (int j = 0; j < n; ++j) 23 mpp[i][j] = inf; 24 mpp[i][i] = 0; 25 } 26 27 for (int i = 0; i < 1<<n; ++i) { 28 for (int j = 0; j < n; ++j) 29 dp[i][j] = inf; 30 val[i] = 0; 31 int temp = i, k = 0; 32 while (temp) { 33 if (temp&1) val[i] += v[k]; 34 k++; 35 temp >>= 1; 36 } 37 } 38 39 while (m--) { 40 int a, b, c; 41 scanf("%d%d%d", &a, &b, &c); 42 mpp[a][b] = mpp[b][a] = min(mpp[a][b], c); 43 } 44 for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) 45 mpp[i][j] = min(mpp[i][j], mpp[i][k]+mpp[k][j]); 46 dp[1<<s][s] = 0; 47 for (int i = 1; i < 1<<n; ++i) { 48 for (int j = 0; j < n; ++j) { 49 if (dp[i][j] > t) continue; 50 for (int k = 0; k < n; ++k) { 51 int state = i|1<<k; 52 dp[state][k] = min(dp[state][k], mpp[j][k]+dp[i][j]); 53 } 54 } 55 } 56 int ans = 0; 57 for (int i = 1; i < 1<<n; ++i) 58 if (dp[i][e] <= t) 59 ans = max(val[i], ans); 60 printf("%d\n", ans); 61 } 62 return 0; 63 }