zoukankan      html  css  js  c++  java
  • hdu 4568(状态压缩dp)

    题意:一张n*m的网格内每个点有话费,还有若干个宝藏,问一个人要走进去拿走所有宝藏在走出来的最小花费。

    思路:看宝藏只有13个直接想到了状压dp[i][j]拿了哪几个前一个为j的最小花费,先bfs+优先队列预处理出最短路,然后记忆化搜索就可。

    代码如下:

      1 /**************************************************
      2  * Author     : xiaohao Z
      3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
      4  * Last modified : 2014-05-15 16:59
      5  * Filename     : C.cpp
      6  * Description     : 
      7  * ************************************************/
      8 
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <cmath>
     14 #include <algorithm>
     15 #include <queue>
     16 #include <stack>
     17 #include <vector>
     18 #include <set>
     19 #include <map>
     20 #define MP(a, b) make_pair(a, b)
     21 #define PB(a) push_back(a)
     22 
     23 using namespace std;
     24 typedef long long ll;
     25 typedef pair<int, int> pii;
     26 typedef pair<unsigned int,unsigned int> puu;
     27 typedef pair<int, double> pid;
     28 typedef pair<ll, int> pli;
     29 typedef pair<int, ll> pil;
     30 
     31 const int INF = 0x3f3f3f3f;
     32 const double eps = 1E-6;
     33 const int LEN = 210;
     34 int Map[LEN][LEN], mp[LEN][LEN], out[LEN], in[LEN], dp[1<<13][20];
     35 int n, m, vn, N;
     36 int xx[] = {0, 0, 1,-1};
     37 int yy[] = {1,-1, 0, 0};
     38 pii vex[LEN];
     39 
     40 bool J(int x, int y){
     41     if(x == 1 || x == n || y == 1 || y == m) return true;
     42     return false;
     43 }
     44 
     45 bool Ja(int x, int y){
     46     if(x>0 && x<=n && y>0 && y<=m) return true;
     47     return false;
     48 }
     49 
     50 struct P{
     51     int x, y, val;
     52     bool operator<(const P a) const
     53     {
     54         return this->val > a.val;
     55     }
     56 };
     57 
     58 P mmp(int a, int b, int c){
     59     P ret;
     60     ret.x = a;ret.y = b;ret.val = c;
     61     return ret;
     62 }
     63 
     64 int Bfs(int sx, int sy, int ex, int ey){
     65     int vis[210][210] = {0};
     66     priority_queue<P> q;
     67     q.push(mmp(sx, sy, 0));
     68     vis[sx][sy] = 1;
     69     while(!q.empty()){
     70         P nv = q.top();q.pop();
     71         int x = nv.x, y = nv.y, val = nv.val;
     72         if(ex < 0 && ey < 0){
     73              if(J(x, y)) return val;
     74         }
     75         else if(x == ex && y == ey) return val;
     76         for(int i=0; i<4; i++){
     77             int tx = x + xx[i];
     78             int ty = y + yy[i];
     79             if(Ja(tx, ty) && !vis[tx][ty]){
     80                 vis[tx][ty] = 1;
     81                 q.push(mmp(tx, ty, val + mp[tx][ty]));
     82             }
     83         }
     84     }
     85     return -1;
     86 }
     87 
     88 void init(){
     89     for(int i=0; i<vn; i++){
     90         for(int j=0; j<vn; j++){
     91             Map[i][j] = Bfs(vex[i].first, vex[i].second, vex[j].first, vex[j].second);
     92         }
     93     }
     94     for(int i=0; i<vn; i++){
     95         int x = vex[i].first, y = vex[i].second;
     96         out[i] = Bfs(x, y, -1, -1);
     97         in[i] = out[i] + mp[x][y];
     98     }
     99 }
    100 
    101 int dfs(int x, int lv){
    102     if(dp[x][lv] != INF) return dp[x][lv];
    103     int cnt = 0;
    104     for(int i=0; i<vn; i++){
    105         if(x & (1 << i)) cnt ++ ;
    106     }
    107     if(cnt == 1) return dp[x][lv] = in[lv];
    108     int ret = INF;
    109     for(int i=0; i<vn; i++){
    110         if((x & (1<<i)) && i != lv){
    111             int &val = Map[i][lv];
    112             ret = min(ret, dfs(x^(1<<lv), i) + val);
    113         }
    114     }
    115     return dp[x][lv] = ret;
    116 }
    117 
    118 int main()
    119 {
    120 //    freopen("in.txt", "r", stdin);
    121 
    122     int T, a, b;
    123     scanf("%d", &T);
    124     while(T--){
    125         scanf("%d%d", &n, &m);
    126         memset(Map, 0x3f, sizeof Map);
    127         memset(mp, 0, sizeof mp);
    128         memset(dp, 0x3f, sizeof dp);
    129         for(int i=1; i<=n; i++){
    130             for(int j=1; j<=m; j++){
    131                 scanf("%d", &mp[i][j]);
    132                 if(mp[i][j] == -1) mp[i][j] = INF;
    133             }
    134         }
    135         scanf("%d", &vn);
    136         for(int i=0; i<vn; i++){
    137             scanf("%d%d", &a, &b);
    138             a++, b++;
    139             vex[i] = MP(a, b);
    140         }
    141         init();
    142         int ans = INF;
    143         for(int i=0; i<vn; i++){
    144             ans = min(ans, dfs((1<<vn)-1, i) + out[i]);
    145         }
    146         if(ans != INF) printf("%d
    ", ans);
    147         else printf("0
    ");
    148     }
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    数据持久化
    在职场久了,才知道这样安排工作日程,方能实现真正的高效
    HIS系统-如何设置单病种结算方式
    HIS系统-你给我制作一个二级库吧!
    开机的一篇英文是怎么回事呢?
    系统故障之-冲动360
    每天看一遍你潦倒至今的原因
    如何配置给自己配置一台适合自己的台式机
    如何配置给自己配置一台电脑
    单网卡、双网卡如何实现同时上内网和外网
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3731308.html
Copyright © 2011-2022 走看看