zoukankan      html  css  js  c++  java
  • LOJ 10172 涂抹果酱

    题目链接:https://loj.ac/problem/10172

    思路:

    看到数据范围,考虑状压$dp$。

    发现每一格有$3$种情况,考虑用三进制来表示。

    枚举所有情况,将可行解与其三进制建立映射关系。

    由于第$k$行上下互不影响,我们可以分别进行$dp$,根据乘法原理相乘即可得到答案。

    为了优化时间,我们可以先将可互相转移的状态记录下来,$dp$时直接查询即可。

    代码:

    #include <bits/stdc++.h>
    const int MAXM = 10050;
    const int p = 1000000;
    typedef int intt;
    #define int long long
    using namespace std;
    vector<int> pb;
    map<int, string> mp;
    bool c[1050][1050];
    int n, m, k, num, ans1, ans2, res, x[MAXM], f[MAXM][50], g[MAXM][50];
    void init(int x) {
        int p = 1, xx = x;
        string s;
        s.clear(); 
        do{
            s += (x % 3 + '0');
        } while(x /= 3);
        while(s.length() != m)
            s += '0';
        reverse(s.begin(), s.end());
        for(int i = 1; i < (int)s.length(); i++) {
            if(s[i] == s[i - 1])
                return ;
        }
        pb.push_back(xx);
        mp[xx] = s;
        //cout << xx << " " << mp[xx] << endl;
    }
    bool check(int x, int y) {
        string s, t;
        s = mp[pb[x]];
        t = mp[pb[y]];
        for(int i = 0; i < m; i++) {
            if(s[i] == t[i])
                return false;
        }
        return true;
    }
    intt main() {
        cin >> n >> m >> k;
        x[0] = -1;
        for(int i = 1; i <= m; i++) {
            cin >> x[i];
            if(x[i] == x[i - 1]) {
                cout << "0" << endl;
                return 0;
            }
            res = res * 3 + (x[i] - 1);
        }
        for(int i = 0; i < (int)pow(3, m); i++) {
            if(res == i)
                num = (int)pb.size();
            init(i);
        }
    //    cout << a[k] << endl << mp[pb[num]] << endl;
        for(int j = 0; j < (int)pb.size(); j++) {
            for(int l = 0; l < (int)pb.size(); l++) {
                c[j][l] = check(j, l);
            }
        }
        f[k][num] = 1;
        for(int i = k - 1; i >= 1; i--) {
            for(int j = 0; j < (int)pb.size(); j++) {
                for(int l = 0; l < (int)pb.size(); l++) {
                    if(c[j][l])
                        f[i][j] = (f[i][j] + f[i + 1][l]) % p;
                }
            }
        }
        g[k][num] = 1;
        for(int i = k + 1; i <= n; i++) {
            for(int j = 0; j < (int)pb.size(); j++) {
                for(int l = 0; l < (int)pb.size(); l++) {
                    if(c[j][l])
                        g[i][j] = (g[i][j] + g[i - 1][l]) % p;
                }
            }
        }
        for(int i = 0; i < (int)pb.size(); i++) {
            ans1 = (ans1 + f[1][i]) % p;
            ans2 = (ans2 + g[n][i]) % p;
        }
        cout << (1ll * ans1 * ans2) % p << endl;
        return 0;
    }
  • 相关阅读:
    matplotlib formatters
    matplotlib locators
    mysql> 12 simple but staple commands
    mysql--> find your databases' local position
    ubuntu16.04安装caffe常见问题及其解决方案
    gitlab使用说明
    vim配置摘要
    shell 提示符个性化设置
    python拼接参数不确定的SQL时防注入问题--条件语句最后拼入
    python_opencv ——图片预处里(二)
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/11729205.html
Copyright © 2011-2022 走看看