zoukankan      html  css  js  c++  java
  • 第七章fill

    总结一下这题的解题步骤:

    1.将问题抽象成某种模型,比如这题就是找出一个有d的状态,且要倒水量最小,平时写的都是路径最小

    ,用的是普通队列,这题要把倒水量最小考虑进去就需要用优先队列

    即:用优先队列的就是在队列中不断找出倒水量最小的状态,然后判断是否一个容器中的水为d

    普通队列可以用来求最短路径长度,即不断的找出离原始状态最近的状态,判断是否有一个容器中的水为d

    所以其实也可以用优先队列来找最短路径只要优先队列是以路径长度来排序的即可

    2.写出更新状态的算法,最简单的就是枚举出所有可能的情况完全不考虑重复的问题,模拟倒水的过程

    3.用具体的例子验证一下算法的正确性

    4.和之前学过的知识做比较,比如以后要是又找个什么路径,都其实可以尝试用优先队列

    #include <iostream>
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    const int maxn=3;
    int cap[maxn];
    const int maxd=210;
    int vis[maxd][maxd][maxd];
    
    struct Node
    {
        int v[3];
        int dist;
    
        bool operator< (const Node& rhs) const
        {
            return dist > rhs.dist;
        }
    
    };
    
    bool matchp(Node n,int d)
    {
        if(n.v[0]==d || n.v[1]==d || n.v[2]==d)
            return true;
        else return false;
    }
    
    int bfs(int a,int b,int c,int& d)
    {
        memset(vis,0,sizeof(vis));
        
        priority_queue<Node> q;
    
        Node st;
        st.v[0]=0;
        st.v[1]=0;
        st.v[2]=cap[2];
        st.dist=0;
    
        q.push(st);
    
        while(!q.empty())
        {
            Node nod=q.top();
            q.pop();
    
            if(matchp(nod,d)) return nod.dist;
    
            //update
            for(int i=0;i<3;i++)
                for(int j=0;j<3;j++)
                    if(i!=j)
                    {
                        Node newnod=nod;
    
                        if(newnod.v[i]>cap[j]-newnod.v[j])
                        {
                            newnod.v[i]-=cap[j]-newnod.v[j];
                            newnod.dist+=cap[j]-newnod.v[j];
                            newnod.v[j]=cap[j];
                        }
                        else
                        {
                            newnod.v[j]+=newnod.v[i];
                            newnod.dist+=newnod.v[i];
                            newnod.v[i]=0;
                        }
    
                        if(vis[newnod.v[0]][newnod.v[1]][newnod.v[2]]==1) continue;
    
                        vis[newnod.v[0]][newnod.v[1]][newnod.v[2]]=1;
                        q.push(newnod);
                    }
        }
    
        return bfs(a,b,c,--d);
    }
    
    
    int main()
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
    
        cap[0]=a;
        cap[1]=b;
        cap[2]=c;
    
        int ans=bfs(a,b,c,d);
    
        printf("%d %d
    ",ans,d);
    
        return 0;
    }
    Yosoro
  • 相关阅读:
    悬线法练习
    Codechef MAY 15 Counting on a directed graph
    Codechef MAY 15 Chef and Balanced Strings
    兔子与兔子
    雪花雪花雪花
    约数之和
    分形之城
    递归实现组合型、指数型、排列型 枚举
    最短Hamilton路径
    六十四位整数乘法
  • 原文地址:https://www.cnblogs.com/tclan126/p/7457688.html
Copyright © 2011-2022 走看看