• 【[Offer收割]编程练习赛15 C】过河问题


    【题目链接】:http://hihocoder.com/problemset/problem/1516

    【题意】

    【题解】

    状态压缩DP+bfs
    这个过河问题能用bfs来搞.涨知识了;
    首先;
    16个人
    容易想到用0..2161来表示3处地方的状态;
    即这一边的岸,船上,以及对岸;
    对于岸上;
    只需要这状态里面,能攻击人的人存在,且它攻击的对象也存在,且能管住这个攻击的人的人不在,则这个状态就是不符合要求的;
    而对于船上;
    则需要一个掌舵人,否则不行;
    然后对于岸上的情况船上的情况也要满足;
    还有就是船上的人数的限制了;
    设f[i][0..1]分别表示某一边状态为i,然后船在某一边(用0和1表示)的最少渡河次数;
    f[(1< < n)-1][0]=0;
    然后每次枚举到对岸的人是哪些就好;
    枚举的方法很巧妙;
    for (int i = (1< < n)-1;i;i=(i-1)&now)
    这个&运算保证了,只有当前存在的人才能过去;然后又能把所有情况都涉及到;
    最后输出f[(1< < n)-1][1]
    程序中can[i]判断i这状态能不能在船上
    can2[i]判断i这个状态能不能在岸上

    【Number Of WA

    0

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 18;
    const int MAX = 7e4;
    
    int n,m,a,b,c,all;
    int son[N],fat[N],boa;
    bool can[MAX],can2[MAX];
    int f[MAX][2];
    queue <pii> dl;
    
    bool check(int statu)
    {
        if ((statu&boa)==0) return false;
        int cnt = 0;
        rep1(i,0,n-1)
        {
            if ((statu>>i)&1)
            {
                cnt++;
                if (((fat[i]&statu)==0) && (son[i]&statu))
                    return false;
            }
        }
        if (cnt>m) return false;
        return true;
    }
    
    bool check2(int statu)
    {
        rep1(i,0,n-1)
        {
            if ((statu>>i)&1)
            {
                if (((fat[i]&statu)==0) && (son[i]&statu))
                    return false;
            }
        }
        return true;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
        cin >> n >> m;
        cin >> a >> b >> c;
        int x,y;
        rep1(i,1,a)
        {
            cin >> x >> y;
            son[x] |= (1<<y);
        }
        rep1(i,1,b)
        {
            cin >> x >> y;
            fat[y]|= (1<<x);
        }
        rep1(i,1,c)
        {
            cin >> x;
            boa |= (1<<x);
        }
        all = (1<<n)-1;
        rep2(i,all,0)
        {
            can[i] = check(i);
            can2[i] = check2(i);
        }
        if (!can2[all]) return cout <<-1<<endl,0;
        ms(f,255);
        f[all][0] = 0;
        dl.push(mp(all,0));
        while (!dl.empty())
        {
            int s = dl.front().fi,k = dl.front().se;dl.pop();
            for (int left = s;left;left=(left-1)&s)
            {
                if (can[left] && can2[all^s^left] && can2[s^left] && can2[all^s])
                {
                    int status = all^s^left;
                    if (f[status][k^1]==-1)
                    {
                        f[status][k^1] = f[s][k]+1;
                        dl.push(mp(status,k^1));
                    }
                }
            }
        }
        cout << f[all][1] << endl;
        return 0;
    }
    
  • 相关阅读:
    MyBatis动态SQL
    Mybatis基础配置
    MyBatis的手动映射与模糊查询
    Struts2框架和SpringMvc框架的区别
    Mybatis和Hibernate框架的区别
    Servlet
    JSP数据交互(二)
    JSP数据交互(一)
    Spark朴素贝叶斯(naiveBayes)
    【安卓开发】Android为什么选择binder
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626382.html
Copyright © 2020-2023  润新知