题目意思是给一个原点坐标,然后再给n个点坐标,每个点有一块砖头,要求把这n个砖头搬到原点。每次最多搬两块,并且走一条路用的时间为坐标距离的平方。求最短时间。n<=20
而且要输出方案,多种方案的话按最小字典序输出。。。
解:如果不需要输出方案的话,那这题就很容易 了。。。
f[i]表示到达i状态的最小时间。一个没有搬的砖头j,f[i|(1<<j)] = min{f[i] + 2*dis(a[j], O)};
再枚举一个没有到达的状态k,f[i|(1<<j)|(1<<k)] = min{f[i] + dis(a[j], O) + dis(a[j], a[k]) + dis(a[k], O)};
f[(1<<n)-1]就是结果。。。
可是。。。这里还要输出最小字典序的方案。蛋疼了。。。
问了一下moonlight131。原来最后这一点只需要一个贪心就可以。
从小到大枚举,如果能到达最终的状态f[(1<<n)-1]则直接输出就可以。。。
1 top = 0; 2 for(i = 0; i < n; ++i) { 3 if(!vis[i]) {ans[top++] = i + 1; vis[i] = true;} 4 5 for(j = i + 1; j < n; ++j) { 6 tt = dis(a[i], p) + dis(a[i], a[j]) + dis(a[j], p); 7 8 if(f[((1<<n)-1)^(1<<i)^(1<<j)] + tt == f[(1<<n)-1]) { //看能否到达最优的状态 9 vis[j] = true; ans[top++] = j + 1; break; 10 } 11 } 12 }