标签:des style blog http io ar color os sp
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 724 Accepted Submission(s): 280
这个题说实话也卡了很多天了 原因是 字典序最小之前没有处理好
之前做过一个很像的题 是一次训练赛德题
那题是这样的 告诉你n个点n 《= 15 的坐标 问一笔画下来最少的路程
那个是这样的dp[i][j]代表状态为i 以第j个点位结尾的最短路
由于|的性质 所以直接往后枚举状态进行转移就可以了
这个题很像
题意是有n个点n<20 每次从初始点出发取回一个或两个点上的石头 取回需要的价值是 距离的平方和
然后问取回所有点的最小价值
这个题dp[i]代表到大i状态的最短路 然后用一个数组表示最短路的最后一个点是啥
最后 由于每次只取回一或者两个点 只要把它拍一下序就好了
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 20; 8 int dp[1 << maxn]; 9 int x[maxn], y[maxn]; 10 int dist[maxn][maxn]; 11 int n, t; 12 int fa[maxn]; 13 14 struct Node { 15 int pr; 16 int x1, x2; 17 }node[1 << maxn]; 18 struct Ans { 19 int flag; 20 int x1, x2; 21 }ans[maxn]; 22 bool cmp(Ans a1, Ans a2) { 23 return a1.x1 < a2.x1; 24 } 25 int xx[1 << maxn]; 26 int an[maxn]; 27 28 void init() { 29 for(int i = 0; i <= n; i++) { 30 for(int j = i; j <= n; j++) { 31 dist[i][j] = dist[j][i] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]); 32 dist[j][i] = dist[i][j]; 33 } 34 } 35 } 36 37 void DP() { 38 memset(dp, 0x3f, sizeof(dp)); 39 dp[0] = 0; xx[0] = 0; 40 fa[0] = 0; 41 int Max = 1 << n; 42 for(int i = 0; i < Max; i++) { 43 if(dp[i] > 1000000000) continue; 44 for(int j = 1; j <= n; j++) { 45 if((i & ( 1 << ( j - 1 ) ) ) == 0 ) { 46 int num = i | ( 1 << ( j - 1 ) ); 47 if(dp[num] > dp[i] + dist[j][0] * 2) { 48 dp[num] = dp[i] + dist[j][0] * 2; 49 xx[num] = j; 50 node[num] = (Node) { i, 0, 0 }; 51 } 52 } 53 } 54 for(int j = 1; j <= n; j++) { 55 for(int k = j + 1; k <= n; k++) { 56 if((i & ( 1 << ( j - 1 ) ) ) == 0 && ( i & ( 1 << ( k - 1) ) ) == 0) { 57 int num = i | ( 1 << ( j - 1 ) ); 58 num |= ( 1 << ( k - 1) ); 59 if(dp[num] > dp[i] + dist[0][j] + dist[j][k] + dist[k][0]) { 60 dp[num] = dp[i] + dist[0][j] + dist[j][k] + dist[k][0]; 61 xx[num] = j; 62 node[num] = (Node) { i, 1, k }; 63 } 64 } 65 } 66 } 67 } 68 } 69 70 void P() { 71 int Max = 1 << n; 72 printf("%d\n", dp[Max - 1]); 73 int id = Max - 1; 74 int cnt = 0; 75 for(int i = 1; i <= n; i++) { 76 if(node[id].x1 == 0) { 77 ans[cnt++] = (Ans) { 1, xx[id], 0 }; 78 } else { 79 ans[cnt++] = (Ans) { 2, min(xx[id],node[id].x2), max(xx[id],node[id].x2)}; 80 i++; 81 } 82 id = node[id].pr; 83 } 84 sort(ans, ans + cnt, cmp); 85 int cn = 0; 86 for(int i = 0; i < cnt; i++) { 87 if(ans[i].flag == 1) { 88 an[cn++] = ans[i].x1; 89 } else { 90 an[cn++] = ans[i].x1; 91 an[cn++] = ans[i].x2; 92 } 93 } 94 for(int i = 0; i < cn; i++) { 95 printf(i == 0 ? "%d" : " %d", an[i]); 96 } puts(""); 97 } 98 99 int main() { 100 scanf("%d",&t); 101 for(int kase = 1; kase <= t; kase++) { 102 scanf("%d %d",&x[0], &y[0]); 103 scanf("%d",&n); 104 for(int i = 1; i <= n; i++) { 105 scanf("%d %d",&x[i], &y[i]); 106 } 107 init(); 108 DP(); 109 printf("Case %d:\n", kase); 110 P(); 111 } 112 return 0; 113 }
标签:des style blog http io ar color os sp
原文地址:http://www.cnblogs.com/zhanzhao/p/4156421.html