• bzoj 2283: [Sdoi2011]火星移民


    六边形插头dp题……

    考虑将这张图推正,就像这样:

    灵魂画师&

    然后就可以编号了,这样就可以和矩形内一样跑插头dp了

    转移一共有16种……防AK好好题

    10.5k代码

    啦啦啦~

    #pragma GCC optimize (2)
    #include <bits/stdc++.h>
    #define N 14
    #define MOD 1000000007
    using namespace std;
    int n;
    int P[N][N * 2];
    struct ct
    {
        int a[N];
        ct()
        {
            for (int i = 0; i < N; ++ i) a[i] = 0;
        }
    };
    inline int operator <(ct x, ct y)
    {
        for (int i = 0; i <= n * 2; ++ i)
            if (x.a[i] != y.a[i]) return x.a[i] < y.a[i];
        return 0;
    }
    inline void maintain(ct &x)
    {
        int s[N]; int tot = 6;
        for (int i = 0; i < N; ++ i) s[i] = 0;
        for (int i = 0; i <= n * 2; ++ i)
            if (x.a[i] > 6 && !s[x.a[i]]) s[x.a[i]] = ++ tot;   
        for (int i = 0; i <= n * 2; ++ i)
            if (x.a[i] > 6) x.a[i] = s[x.a[i]];
    }
    struct p2
    {
        int fr, sc;
    };
    inline p2 mix(p2 x, p2 y)
    {
        if (x.fr < y.fr) return x;
        else if (x.fr > y.fr) return y;
        else return (p2){x.fr, (x.sc + y.sc) >= MOD? (x.sc + y.sc) - MOD: (x.sc + y.sc)};
    }
    map <ct, p2> F[2]; ct fin;
    int tmp, vis[4];
    void print(ct x)
    {
        for (int i = 0; i <= 2 * n; ++ i) printf("%d ", x.a[i]);
        puts("");
    }
    int main()
    {
        while (scanf("%d", &n) == 1)
        {
        for (int i = 1; i <= n * 2; ++ i)
            for (int j = 1; j <= n * 4; ++ j)
                P[i][j] = 4;
        for (int i = 1; i <= n; ++ i)
            for (int j = n * 2 - i * 2 + 2; j <= n * 4; ++ j)
                scanf("%d", &P[i][j]);
        for (int i = n + 1; i <= n * 2; ++ i)
            for (int j = 1; j <= n * 6 - i * 2 + 1; ++ j)
                scanf("%d", &P[i][j]);
             
            for (int i = 0; i < 4; ++ i) vis[i] = 0;
        for (int i = 1; i <= n * 2; ++ i)
            for (int j = 1; j <= n * 4; ++ j)
                if (P[i][j] <= 3 && P[i][j])
                {
                    if (!vis[P[i][j]])
                        vis[P[i][j]] = 1, P[i][j] = P[i][j] * 2 - 1;
                    else
                        P[i][j] = P[i][j] * 2;
                }
                else if (P[i][j]) P[i][j] = 7;
            /*
        for (int i = 1; i <= n * 2; ++ i)
        {
            for (int j = 1; j <= n * 4; ++ j)
                printf("%d ", P[i][j]);
            puts("");
        }*/
         
        tmp = 0;
        F[0].clear(); F[1].clear();
        F[0][fin] = (p2){0, 1};
        for (int i = 1; i <= n * 2; ++ i)
        {
            for (int j = 1; j <= n * 2; ++ j)
            {
                tmp ^= 1; F[tmp].clear();
                ct pf, nf; p2 ps, ns;
                for (map <ct, p2> :: iterator it = F[!tmp].begin(); it != F[!tmp].end(); ++ it)
                {
                    pf = it -> first; ps = it -> second;
                //  printf("%d %d %d : ", i, j * 2 - 1, ps.fr); print(pf);
                    if (!P[i][j * 2 - 1])
                    {
                        if (((bool)(pf.a[j - 1]) && (bool)(pf.a[j])))
                        {
                            if (pf.a[j - 1] <= 6 && pf.a[j] <= 6)
                            {
                                if ((pf.a[j - 1] + 1) / 2 == (pf.a[j] + 1) / 2)
                                {
                                    nf = pf; ns = ps; ns.fr ++;
                                    nf.a[j - 1] = nf.a[j] = 0;
                                    if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                                }
                            }
                            else if (pf.a[j - 1] != pf.a[j])
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                int mn = min(pf.a[j - 1], pf.a[j]), mx = max(pf.a[j - 1], pf.a[j]);
                                for (int k = 0; k <= n * 2; ++ k)
                                    if (pf.a[k] == mx) nf.a[k] = mn;
                                nf.a[j - 1] = nf.a[j] = 0; maintain(nf);
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                        else if ((bool)(pf.a[j - 1]) ^ (bool)(pf.a[j]))
                        {
                            nf = pf; ns = ps; ns.fr ++;
                            nf.a[j - 1] = 0;
                            nf.a[j] = pf.a[j - 1] + pf.a[j]; maintain(nf);
                            if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                        }
                        else
                        {
                            nf = pf; ns = ps;
                            if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                        }
                    }
                    else if (P[i][j * 2 - 1] == 7)
                    {
                        if (!(bool)(pf.a[j - 1]) && !(bool)(pf.a[j]))
                        {
                            nf = pf; ns = ps;
                            if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                        }
                    }
                    else
                    {
                        if ((bool)(pf.a[j - 1]) ^ (bool)(pf.a[j]))
                        {
                            if (pf.a[j - 1] + pf.a[j] <= 6)
                            {
                                if ((pf.a[j - 1] + pf.a[j] + 1) / 2 == (P[i][j * 2 - 1] + 1) / 2)
                                {
                                    nf = pf; ns = ps; ns.fr ++;
                                    nf.a[j - 1] = nf.a[j] = 0;
                                    if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                                }
                            }
                            else
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                int mx = max(pf.a[j - 1], pf.a[j]);
                                for (int k = 0; k <= n * 2; ++ k)
                                    if (pf.a[k] == mx) nf.a[k] = P[i][j * 2 - 1];
                                nf.a[j - 1] = nf.a[j] = 0; maintain(nf);
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                        else if (!(bool)(pf.a[j - 1]) && !(bool)(pf.a[j]))
                        {
                            nf = pf; ns = ps; ns.fr ++;
                            nf.a[j] = P[i][j * 2 - 1];
                            if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                        }
                    }
                }
                 
                 
                tmp ^= 1; F[tmp].clear();      
                for (map <ct, p2> :: iterator it = F[!tmp].begin(); it != F[!tmp].end(); ++ it)
                {
                    pf = it -> first; ps = it -> second;
                //  printf("%d %d %d : ", i, j * 2, ps.fr); print(pf);
                    if (!P[i][j * 2])
                    {
                        if (pf.a[j])
                        {
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                nf.a[j - 1] = pf.a[j];
                                nf.a[j] = 0;
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                nf.a[j - 1] = 0;
                                nf.a[j] = pf.a[j];
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                        else
                        {
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                nf.a[j - 1] = nf.a[j] = N - 1; maintain(nf);
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                            {
                                nf = pf; ns = ps;
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                    }
                    else if (P[i][j * 2] == 7)
                    {
                        if (!pf.a[j])
                        {
                            nf = pf; ns = ps;
                            if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                        }
                    }
                    else
                    {
                        if (pf.a[j])
                        {
                            if (pf.a[j] <= 6)
                            {
                                if ((pf.a[j] + 1) / 2 == (P[i][j * 2] + 1) / 2)
                                {
                                    nf = pf; ns = ps; ns.fr ++;
                                    nf.a[j - 1] = nf.a[j] = 0;
                                    if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                                }
                            }
                            else
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                for (int k = 0; k <= n * 2; ++ k)
                                    if (pf.a[k] == pf.a[j]) nf.a[k] = P[i][j * 2];
                                nf.a[j] = 0; maintain(nf);
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                        else
                        {
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                nf.a[j - 1] = P[i][j * 2];
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                            {
                                nf = pf; ns = ps; ns.fr ++;
                                nf.a[j] = P[i][j * 2];
                                if (!F[tmp].count(nf)) F[tmp][nf] = ns; else F[tmp][nf] = mix(F[tmp][nf], ns);
                            }
                        }
                    }
                }
            }
             
             
            tmp ^= 1; F[tmp].clear();          
            for (map <ct, p2> :: iterator it = F[!tmp].begin(); it != F[!tmp].end(); ++ it)
            {
                ct pf = it -> first, nf; p2 ps = it -> second;
                if (!pf.a[n * 2])
                {
                    for (int j = 1; j <= n * 2; ++ j) nf.a[j] = pf.a[j - 1];
                    F[tmp][nf] = ps;
                }
            }
        }
        p2 ans;
        if (F[tmp].count(fin)) ans = F[tmp][fin], ans.fr -= 3;
        else ans = (p2){-1, -1};
        printf("%d %d
    ", ans.fr, ans.sc);
        }
    }
  • 相关阅读:
    利用线程池爬虫
    多任务协程怎么写
    利用协程多任务协程爬取前几页投诉网
    cookie的处理和代理池的建立
    bs4和xpath的用法
    怎么使用Ip代理词
    雪球网新闻标题的爬取
    爬虫学习的基础篇
    小说文本爬取
    24 张图彻底弄懂九大常见数据结构
  • 原文地址:https://www.cnblogs.com/AwD-/p/6306757.html
Copyright © 2020-2023  润新知