zoukankan      html  css  js  c++  java
  • 【路径寻找问题】UVa 10603

    如家大神书上的例题。第一次接触也是按代码敲得。敲的过程感觉很直观。但自己写估计会写的乱七八糟。以后不能砍得难就不愿意做这种题。否则只能做一些水题了。(PS:48)

    紫书

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<queue>
     6 using namespace std;
     7 const int maxn = 205;
     8 struct Node
     9 {
    10     int v[3];
    11     int dist; //总倒水量
    12     bool operator < (const Node& a) const
    13     {
    14         return dist > a.dist;
    15     }
    16 };
    17 int vis[maxn][maxn], ans[maxn];
    18 int cap[3];
    19 void update_ans(const Node& u)
    20 {
    21     for(int i = 0; i < 3; i++)
    22     {
    23         int d = u.v[i]; //当前状态下每个杯的水量;
    24         if(ans[d] < 0 || u.dist < ans[d])
    25             ans[d] = u.dist;
    26     }
    27 }
    28 void solve(int a, int b, int c, int d)
    29 {
    30     cap[0] = a; cap[1] = b; cap[2] = c;
    31     memset(vis, 0, sizeof(vis));
    32     memset(ans, -1, sizeof(ans));
    33     priority_queue<Node> q; //优先队列应用!
    34 
    35     Node start;
    36     start.v[0] = 0; start.v[1] = 0; start.v[2] = c; start.dist = 0;
    37     q.push(start);
    38 
    39     vis[0][0] = 1;
    40     while(!q.empty())
    41     {
    42         Node u = q.top(); q.pop(); //选择倒水量少的扩展
    43         update_ans(u);
    44         if(ans[d] >= 0) break;
    45         for(int i = 0; i < 3; i++)
    46             for(int j = 0; j < 3; j++)
    47         {//把水从i倒入j
    48             if(i == j) continue;
    49             if(u.v[i] == 0 || u.v[j] == cap[j]) continue; //i没水或j满
    50             int amount = min(cap[j], u.v[i]+u.v[j]) - u.v[j]; //从i倒入j中水的量
    51             Node v;
    52             memcpy(&v, &u, sizeof(u));
    53             v.v[i] -= amount; v.v[j] += amount; v.dist += amount;
    54             if(!vis[v.v[0]][v.v[1]]) //状态记忆;因总水量一定,故只知道其中两个杯子的水量就可知当前状态。故记忆数组用二维即可
    55             {
    56                 vis[v.v[0]][v.v[1]] = 1;
    57                 q.push(v);
    58             }
    59         }
    60     }
    61     while(d >= 0) //若达不到,则尽可能接近
    62     {
    63         if(ans[d] >= 0)
    64         {
    65             printf("%d %d
    ", ans[d], d);
    66             return ;
    67         }
    68         d--;
    69     }
    70 }
    71 int main()
    72 {
    73     int T; scanf("%d", &T);
    74     while(T--)
    75     {
    76         int a, b, c, n;
    77         scanf("%d%d%d%d", &a, &b, &c, &n);
    78         solve(a, b, c, n);
    79     }
    80     return 0;
    81 }

    P205.直接上代码

  • 相关阅读:
    POJ 1651:Multiplication Puzzle(区间DP)
    POJ 2955:Brackets(区间DP)
    LightOJ 1422:Halloween Costumes(区间DP入门)
    Gym 101257G:24(尺取)
    Codeforces 777D:Cloud of Hashtags(水题)
    Gym 101257B:2Trees(DFS+思维)
    Codeforces 777C:Alyona and Spreadsheet(思维)
    Codeforces 776C:Molly's Chemicals(思维)
    HDU-3440 House Man
    BZOJ-1202 狡猾的商人
  • 原文地址:https://www.cnblogs.com/LLGemini/p/4309966.html
Copyright © 2011-2022 走看看