给一个10*10的方格, 每个格子里面有0-9,走到一个格子, 就要在这个格子待一段时间, 时间长度为这个格子的数字。 从左上角走到右下角, 要求0-9必须每种格子都要走到, 输出最短时间。
在平常dp的基础上多开一维, 然后用二进制代表哪些走到过哪些没有走到过, 最后输出dp[10][10][1023]就可以。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 using namespace std; 14 #define pb(x) push_back(x) 15 #define ll long long 16 #define mk(x, y) make_pair(x, y) 17 #define lson l, m, rt<<1 18 #define mem(a) memset(a, 0, sizeof(a)) 19 #define rson m+1, r, rt<<1|1 20 #define mem1(a) memset(a, -1, sizeof(a)) 21 #define mem2(a) memset(a, 0x3f, sizeof(a)) 22 #define rep(i, n, a) for(int i = a; i<n; i++) 23 #define fi first 24 #define se second 25 typedef pair<int, int> pll; 26 const double PI = acos(-1.0); 27 const double eps = 1e-8; 28 const int mod = 1e9+7; 29 const int inf = 1061109567; 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 31 int dp[10][10][1<<10], a[10][10]; 32 int main() 33 { 34 for(int i = 0; i<10; i++) 35 for(int j = 0; j<10; j++) 36 scanf("%d", &a[i][j]); 37 mem2(dp); 38 dp[0][0][1<<a[0][0]] = a[0][0]; 39 int tmp = (1<<a[0][0]); 40 for(int i = 1; i<10; i++) { 41 int x = tmp|(1<<a[0][i]); 42 dp[0][i][x] = dp[0][i-1][tmp]+a[0][i]; 43 tmp = x; 44 } 45 tmp = (1<<a[0][0]); 46 for(int i = 1; i<10; i++) { 47 int x = tmp|(1<<a[i][0]); 48 dp[i][0][x] = dp[i-1][0][tmp]+a[i][0]; 49 tmp = x; 50 } 51 for(int i = 1; i<10; i++) { 52 for(int j = 1; j<10; j++) { 53 for(int k = 0; k<1024; k++) { 54 if(dp[i][j-1][k]!=inf) { 55 dp[i][j][k|(1<<a[i][j])] = min(dp[i][j][k|(1<<a[i][j])], dp[i][j-1][k]+a[i][j]); 56 } 57 if(dp[i-1][j][k]!=inf) { 58 dp[i][j][k|(1<<a[i][j])] = min(dp[i][j][k|(1<<a[i][j])], dp[i-1][j][k]+a[i][j]); 59 } 60 } 61 } 62 } 63 cout<<dp[9][9][1023]; 64 return 0; 65 }