HDU 4385 Moving Bricks (状态dp+贪心)

  题目意思是给一个原点坐标,然后再给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         }

 

  

 

 

 

posted @ 2012-08-27 20:08  AC_Von  阅读(417)  评论(0编辑  收藏  举报