题目链接:http://lightoj.com/volume_showproblem.php?problem=1119
题目大意:给你n份工作,每份工作 i 的花费是 p[i][i] ,在做第i份工作之前,如果之前做了第j份工作,就需要加上p[i][j],问你怎么排列工作才能使得花费最少
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 typedef long long LL; 15 16 int p[20][20], dp[20][1<<15]; 17 int main() 18 { 19 int t, n; 20 scanf("%d", &t); 21 for(int ca = 1; ca <= t; ca++) 22 { 23 scanf("%d", &n); 24 for(int i = 1; i <= n; i++) 25 for(int j = 1; j <= n; j++) 26 scanf("%d", &p[i][j]); 27 memset(dp, INF, sizeof(dp)); 28 for(int i = 0; i < n; i++) 29 dp[1][1<<i] = p[i+1][i+1]; 30 for(int i = 2; i <= n; i++) 31 { 32 for(int j = 1; j < (1 << n); j++) 33 { 34 int te = j, s = 0; 35 while(te) 36 { 37 if(te % 2) 38 s++; 39 te >>= 1; 40 } 41 if(s != i-1) 42 continue; 43 for(int l1 = 0; l1 < n; l1++) 44 { 45 if((1<<l1) & j) 46 continue; 47 int sum = dp[i-1][j] + p[l1+1][l1+1]; 48 for(int k = 0; k < n; k++)//1 49 if((1<<k)&j) 50 sum += p[l1+1][k+1]; 51 dp[i][j|(1<<l1)] = min(dp[i][j|(1<<l1)], sum); 52 } 53 } 54 } 55 printf("Case %d: %d\n", ca, dp[n][(1<<n)-1]); 56 } 57 return 0; 58 }