洛谷T31039 九尾狐吃棉花糖
小伙伴出的题。
一眼看出是状压DP裸题。回忆poj2288 islands and bridges,然后就很好写了。
啪啪啪打了个状压DP出来(晚上寝室写的,其实是记忆化搜索),发现sum总是INF
然后发现:printf函数调用的貌似不是运行solve之后的,而是还未运行solve时的值。
于是分开写就A了。
出题者跑了一秒多,貌似用的二分...反正不怎么看得懂。
果然DP大法吼哇!
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 typedef long long LL; 5 using std::max; 6 using std::min; 7 const int N = 17; 8 LL INF; 9 int n; 10 11 LL f[1 << N][N], sum[1 << N][N], G[N][N]; 12 13 void cal(int sta) { 14 int t[N]; 15 for(int i = 0; i < n; i++) { 16 t[i] = (sta >> i) & 1; 17 } 18 for(int i = n - 1; i >= 0; i--) { 19 printf("%d", t[i]); 20 } 21 return; 22 } 23 24 LL solve(int i, int j) { 25 26 if(f[i][j] != INF) { 27 //printf("solve: "); 28 //cal(i); 29 //printf(" %d ans = %lld sum = %lld \n", j, f[i][j], sum[i][j]); 30 return f[i][j]; 31 } 32 33 int ct = 0; 34 for(int ii = 0; ii < n; ii++) { 35 ct += (i >> ii) & 1; 36 } 37 if(ct < 2) { 38 f[i][j] = INF - 1; 39 return INF - 1; 40 } 41 42 LL ans = INF - 1, len = INF - 1; 43 int sta = ((~(1 << j)) & i); 44 for(int ii = 0; ii < n; ii++) { 45 if(!(G[ii][j] && ((i >> ii) & 1))) { 46 continue; 47 } 48 LL t_ans = max(solve(sta, ii), G[ii][j]); 49 LL t_len = sum[sta][ii] + G[ii][j]; 50 if(t_ans < ans) { 51 ans = t_ans; 52 len = t_len; 53 } 54 else if(ans == t_ans) { 55 len = min(len, t_len); 56 } 57 } 58 f[i][j] = ans; 59 sum[i][j] = len; 60 //printf("solve: "); 61 //cal(i); 62 //printf(" %d ans = %lld sum = %lld \n", j, ans, len); 63 return ans; 64 } 65 66 int main() { 67 memset(f, 0x7f, sizeof(f)); 68 memset(sum, 0x7f, sizeof(sum)); 69 INF = sum[1][1]; 70 71 int m, x, y; 72 LL R, z; 73 scanf("%d%d%lld", &n, &m, &R); 74 for(int i = 1; i <= m; i++) { 75 scanf("%d%d%lld", &x, &y, &z); 76 x--; y--; 77 if(x == y || z > R) continue; 78 if(G[x][y]) z = min(z, G[x][y]); 79 G[x][y] = G[y][x] = z; 80 } 81 for(int i = 1; i < n; i++) { 82 if(G[0][i]) { 83 int sta = 1 | (1 << i); 84 f[sta][i] = G[0][i]; 85 sum[sta][i] = G[0][i]; 86 } 87 } 88 int ed = (1 << n) - 1; 89 LL ans = solve(ed, (n - 1)); 90 LL len = sum[ed][n - 1]; 91 if(ans >= INF - 1) { 92 printf("wuwuwu~"); 93 } 94 else { 95 printf("%lld %lld", ans, len); 96 } 97 return 0; 98 }