ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[数据丢失]Ants

2021-12-25 16:05:53  阅读:158  来源: 互联网

标签:插头 __ int void Ants 丢失 inline 数据 define


壹、题目描述 ¶

  \(\color{red}{\mathcal{The\;Portal\;Has\;Been\;Distoryed.}}\)

  在一张 \(n \times n\) 的网格图上每个格子都有一只蚂蚁。每只蚂蚁将会同时往上下左右 \(4\) 个方向中的某个方向前进一步。一个合法的方案是指所有蚂蚁移动完后仍然在网格内,且每个格子仍然有且仅有一只蚂蚁。并且,蚂蚁的对冲是被禁止的

  请统计出所有合法的方案的总数,数据范围 \(n\le 10\).

贰、题解 ¶

  第一道插头 \(\rm DP\),有被恶心到......

  考虑使用轮廓线 \(\rm DP\),定义几种插头:

  1. 空插头,值为 \(0\),就是一个空格子;

  2. 外插头,值为 \(1\),是 \(\framebox[2][]{\downarrow}\);

  3. 内插头,值为 \(2\),是 \(\framebox[2]{\uparrow}\);

  定义轮廓线表示已决策格子和未决策格子的分界线,并用一个 \(3\) 进制的数表示轮廓线上从左到右的 \(n+1\) 个插头,举个例子,就是这个样子:

  然后,我们定义 \(f(i,j,S)\) 表示考虑到格子 \((i,j)\),轮廓线上的插头状态为 \(S\) 的情况,不难看出,\(S\) 是一个在 \(3\) 进制下有 \(n+1\) 位的数。

  初始状态是下面这两种状态:

  前者是 \(f(1,1,(12)_3)\),后者是 \(f(1,1,(21)_3)\);

  而目标状态就是 \(f(n,n,0)\);

  考虑转移的时候就暴力讨论就可以了,考虑在 \((i,j)(j<n)\) 格子的时候,如果我们要将轮廓线扩展到 \((i,j+1)\),那么轮廓线会出现什么变化。对于所有的 \(9\) 中情况暴力讨论即可。

  对于 \(j=n\) 的情况,涉及换行,第 \(n + 1\) 个插头必须为空插头,然后在最前面插入一个空插头。弄到位运算上就是左移一位,然后去掉最高位,不过转移的前提是最高位为 \(0\).

  讨论的时候注意一下细节就行了,各种情况看代码即可。总时间复杂度 \(\mathcal O(n^23^{n+1})\). 注意开 long long.

叁、参考代码 ¶

/** @author Arextre */

#include <bits/stdc++.h>
using namespace std;

#define USING_FREAD
// #define NDEBUG
// #define NCHECK
#include <cassert>

/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */
namespace Elaina {

#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER
#ifdef NCHECK
# define iputs(Content) ((void)0)
# define iprintf(Content, argvs...) ((void)0)
#else
# define iputs(Content) fprintf(stderr, Content)
# define iprintf(Content, argvs...) fprintf(stderr, Content, argvs)
#endif

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void getmin(T& x, const T rhs) { x = min(x, rhs); }
template<class T> inline void getmax(T& x, const T rhs) { x = max(x, rhs); }

#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
    static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
    return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI getchar()
#endif

template<class T> inline T readret(T x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    return f ? -x : x;
}
template<class T> inline void readin(T& x) {
    x = 0; int f = 0; char c;
    while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
    for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
    if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
    readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
    if (x < 0) putchar('-'), x = -x;
    static int __stk[55], __bit = 0;
    do __stk[++__bit] = x % 10, x /= 10; while (x);
    while (__bit) putchar(__stk[__bit--] ^ 48);
    putchar(c);
}

} // namespace Elaina
using namespace Elaina;

const int maxn = 10;
const int maxs = 177147;

int n;
inline void input() { readin(n); }

/** @brief 1 means leaving & 2 means coming */
ll f[maxn + 5][maxn + 5][maxs + 5];
inline int trans(int s) {
    for (int ret = 0; ; ret = ret * 3 + (s % 10), s /= 10)
        if (!s) return ret;
}
int sys[20];
inline void prelude() {
    sys[0] = 1;
    rep (i, 1, 15) sys[i] = sys[i - 1] * 3;
}
inline int Lsh(int val, int pos) {
    assert(pos >= 0); assert(pos <= 15);
    return val * sys[pos];
}
inline int Rsh(int val, int pos) {
    assert(pos >= 0); assert(pos <= 15);
    return val / sys[pos];
}
int replace(int s, int p, int v) {
    assert(0 <= p); assert(p <= 15);
    int x = s / sys[p] % 3;
    return s + (v - x) * sys[p];
}
int getp(int s, int p) {
    assert(0 <= p); assert(p <= 15);
    return Rsh(s, p) % 3;
}
inline void solve() {
    f[1][1][trans(21)] = f[1][1][trans(12)] = 1;
    int U = sys[n + 1];
    rep (i, 1, n) rep (j, 0, n) rep (s, 0, U - 1) if (f[i][j][s]) {
        if (j == n) {
            if (getp(s, j)) continue; // invalid
            f[i + 1][0][Lsh(s, 1) % U] = f[i][j][s];
        }
        else {
            if (getp(s, j) == 0 && getp(s, j + 1) == 0) {
                f[i][j + 1][replace(replace(s, j, 2), j + 1, 1)] += f[i][j][s];
                f[i][j + 1][replace(replace(s, j, 1), j + 1, 2)] += f[i][j][s];
            }
            else if (getp(s, j) == 0 && getp(s, j + 1) == 1) {
                f[i][j + 1][replace(replace(s, j, 1), j + 1, 0)] += f[i][j][s];
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 1)] += f[i][j][s];
            }
            else if (getp(s, j) == 0 && getp(s, j + 1) == 2) {
                f[i][j + 1][replace(replace(s, j, 2), j + 1, 0)] += f[i][j][s];
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 2)] += f[i][j][s];
            }
            else if (getp(s, j) == 1 && getp(s, j + 1) == 0) {
                f[i][j + 1][replace(replace(s, j, 1), j + 1, 0)] += f[i][j][s];
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 1)] += f[i][j][s];
            }
            else if (getp(s, j) == 1 && getp(s, j + 1) == 1) ; // invalid
            else if (getp(s, j) == 1 && getp(s, j + 1) == 2) {
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 0)] += f[i][j][s];
            }
            else if (getp(s, j) == 2 && getp(s, j + 1) == 0) {
                f[i][j + 1][replace(replace(s, j, 2), j + 1, 0)] += f[i][j][s];
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 2)] += f[i][j][s];
            }
            else if (getp(s, j) == 2 && getp(s, j + 1) == 1) {
                f[i][j + 1][replace(replace(s, j, 0), j + 1, 0)] += f[i][j][s];
            }
            else if (getp(s, j) == 2 && getp(s, j + 1) == 2) ; // invalid
        }
    }
    writln(f[n][n][0]);
}

signed main() {
    prelude();
    input();
    solve();
    return 0;
}

标签:插头,__,int,void,Ants,丢失,inline,数据,define
来源: https://www.cnblogs.com/Arextre/p/15730737.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有