zoukankan      html  css  js  c++  java
  • BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) 

    ---------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    #define b(x) (1 << (x))
    typedef unsigned int matrix[100][100];
    const int maxn = 9;
     
    bool OK[b(maxn)];
    int N, n, U, M, D, p, k;
    matrix Q, res, mat;
     
    void Init() {
    scanf("%d%d%d%d", &N, &n, &p, &k);
    U = M = D = 0;
    for(int i = 0; i < p; i++) {
    int v; scanf("%d", &v);
    if(v) U |= b(i);
    }
    for(int i = 0; i < p; i++) {
    int v; scanf("%d", &v);
    if(v) M |= b(i);
    }
    for(int i = 0; i < p; i++) {
    int v; scanf("%d", &v);
    if(v) D |= b(i);
    }
    M ^= b(k);
    }
     
    bool chk(int x) {
    for(int i = 0; i < n; i++) if(x & b(i)) {
    if(i <= k && ((M >> (k - i)) & x)) return 0;
    if(i > k && ((M << (i - k)) & x)) return 0;
    }
    return true;
    }
     
    unsigned int Jud(int x, int y) {
    for(int i = 0; i < n; i++) {
    if(b(i) & x) {
    if(i <= k && ((D >> (k - i)) & y)) return 0U;
    if(i > k && ((D << (i - k)) & y)) return 0U;
    }
    if(b(i) & y) {
    if(i <= k && ((U >> (k - i)) & x)) return 0U;
    if(i > k && ((U << (i - k)) & x)) return 0U;
    }
    }
    return 1U;
    }
     
    void Work() {
    for(int s = b(n); s--; ) OK[s] = chk(s);
    for(int i = b(n); i--; ) if(OK[i])
    for(int j = b(n); j--; ) if(OK[j])
    Q[j][i] = Jud(i, j);
    for(int i = b(n); i--; ) res[i][i] = 1U;
    for(N--; N; N >>= 1) {
    if(N & 1) {
    for(int i = b(n); i--; )
    for(int j = b(n); j--; ) {
    mat[i][j] = res[i][j];
    res[i][j] = 0;
    }
    for(int k = b(n); k--; )
    for(int i = b(n); i--; )
    for(int j = b(n); j--; )
    res[i][j] += Q[i][k] * mat[k][j];
    }
    for(int i = b(n); i--; )
    for(int j = b(n); j--; ) {
    mat[i][j] = Q[i][j];
    Q[i][j] = 0;
    }
    for(int k = b(n); k--; )
    for(int i = b(n); i--; )
    for(int j = b(n); j--; )
    Q[i][j] += mat[i][k] * mat[k][j];
    }
    unsigned int ans = 0;
    for(int i = b(n); i--; ) if(OK[i])
    for(int j = b(n); j--; ) if(OK[j])
    ans += res[i][j];
    printf("%u ", ans);
    }
     
    int main() {
    Init();
    Work();
    return 0;
    }

    --------------------------------------------------------------------------------------------- 

    4000: [TJOI2015]棋盘

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 355  Solved: 159
    [Submit][Status][Discuss]

    Description

     

    Input

    输入数据的第一行为两个整数N,M表示棋盘大小。第二行为两个整数P,K,
    表示攻击范围模板的大小,以及棋子在模板中的位置。接下来三行,
    每行P个数,表示攻击范围的模版。每个数字后面一个空格。

    Output

     一个整数,表示可行方案Mod 2 ^32

    Sample Input

    2 2
    3 1
    0 1 0
    1 1 1
    0 1 0

    Sample Output

    7

    HINT

     1<=N<=10^6,1<=M<=6

    Source

  • 相关阅读:
    静态页面设置缓存、动态页面设缓存
    未能加载文件或程序集“WebGrease, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
    CS0016: 未能写入输出文件“c:WindowsMicrosoft.NETFrameworkv4.0.30319Temporary ASP.NET Files
    asp.net mvc 重定向
    win8 应用商店。 app下载的音乐和视频软件能打开,不能正常播放 解决方法
    JS 阻止事件冒泡
    ASP.NET MVC4空MVC项目添加脚本压缩和合并
    TabHost说明
    colors.xml
    MMU (一)
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5156798.html
Copyright © 2011-2022 走看看