TJOI2015 棋盘

Description

Input

Output

Sample Input

2 23 10 1 01 1 10 1 0

Sample Output

7

Data Constraint

这题有个巨坑的地方,棋子在第1行,每k列,行和列都是从0开始编号的!!!也就是实际是第2行,第k+1列!!!

看出来后就一大水题了。

经过转换可以使得每个棋子都只影响下一行,又由于列只有6,所以用状压解

f[i][[j]表示每i行状态为j的方案,然后我们发现每2行之间的转移是一样的,所以可以预处理转移矩阵,再矩乘加快速幂优化即可

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
typedef unsigned int ui;

vector<int> lim[4];

struct Matrix{
    ui a[65][65];
}pc,d;

ui ans;
ui f[1011];
int i,j,k,p,m,nj,l,n,L,sy;
int a[4][10];

Matrix operator *(Matrix a,Matrix b)
{
    Matrix c;
    memset(c.a,0,sizeof(c.a));
    int i,j,k;
    for(i=0;i<(1<<m);i++)
        for(k=0;k<(1<<m);k++)if(a.a[i][k]){
            for(j=0;j<(1<<m);j++)c.a[i][j]+=a.a[i][k]*b.a[k][j];
        }
    return c;
}

Matrix mi(Matrix a,int z)
{
    Matrix l;
    bool pz;
    int i,j;
    pz=true;
    while(z){
        if(z%2==1){
            if(pz){
                pz=false;
                for(i=0;i<(1<<m);i++)
                    for(j=0;j<(1<<m);j++)l.a[i][j]=a.a[i][j];
            }
            else l=l*a;
        }
        a=a*a;
        z/=2;
    }
    return l;
}

bool check(int ls,int ts)
{
    int i,j,sy,k;
    for(i=0;i<m;i++)if((ls&(1<<i))){
        for(j=0;j<lim[3].size();j++){
            k=lim[3][j];
            sy=i+1+k-L;
            if(sy>0&&sy<=m){
                if((ts&(1<<(sy-1))))return false;
            }
        }
    }
    for(i=0;i<m;i++)if((ts&(1<<i))){
        for(j=0;j<lim[2].size();j++){
            k=lim[2][j];
            sy=i+1+k-L;
            if(sy>0&&sy<=m){
                if(sy!=i+1&&(ts&(1<<(sy-1))))return false;
            }
        }
    }
    return true;
}

int main()
{
    scanf("%d%d",&n,&m);
    scanf("%d%d",&p,&L);
    L++;
    for(i=1;i<=3;i++)
        for(j=1;j<=p;j++){
            scanf("%d",&a[i][j]);
            if(a[2][j])lim[2].push_back(j);
            if(a[3][j])lim[3].push_back(j);
        }
    for(i=1;i<=p;i++)if(a[1][i]){
        sy=L+L-i;
        lim[3].push_back(sy);
    }
    for(i=0;i<(1<<m);i++)
        for(j=0;j<(1<<m);j++)if(check(i,j))pc.a[i][j]=1;
    d=mi(pc,n);
    for(i=0;i<(1<<m);i++)if(pc.a[0][i])f[i]++;
    for(i=0;i<(1<<m);i++)ans+=f[i]*d.a[i][0];
    printf("%u\n",ans);
}
时间: 2024-10-31 09:11:03

TJOI2015 棋盘的相关文章

BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define b(x) (1 <&l

BZOJ4000 [TJOI2015]棋盘

首先是状态压缩DP... 然后我们发现转移都是一样的...可以矩阵优化... 于是做完啦QAQQQ 题目读不懂?恩多读几遍就读懂了,诶诶诶!别打我呀! 1 /************************************************************** 2 Problem: 4000 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:208 ms 7 Memory:920 kb 8 **********

【bzoj4000】[TJOI2015]棋盘 dp+矩乘

题目坑爹,行列是从0开始算的,所以样例中是指最中间那个1为棋子 f[i][S]表示考虑到第i行,第i行状态为S的方案数 矩乘优化即可 开内存小了1,蛋疼. #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define ll unsigned int using nam

TJOI2015 day2解题报告

其实第三题还没看啦~~前两题就总结下吧 T1:[TJOI2015]旅游 描述:(BZ没题面只能口述了..)一个人在一棵树上走,每次从a->b会进行一次贸易(也就是在这条路径上买入物品然后在后面卖出)然后每次经过一个点该点的物品价格会上涨v,求每次贸易的最大获利 很裸的一道树链剖分,就是题目描述太不明白了..这样就是在某条路径上找到某个点减去后面路径的最小点的值的最大值.可以用线段树的区间合并解决.就是在求答案时的合并答案上方向搞反了查了很久...以前也犯过着种错误,以后不能再犯了.. CODE:

联赛之前的题表(已完成)汇总(可能有遗漏)

联赛之前的搞搞(其实是懒得分类) 博弈论 poj3537 poj1704 hdu5996两个插头 HDU1693 Eat the Trees COGS1283. [HNOI2004] 邮递员kdtree板子1941: [Sdoi2010]Hide and Seek旋转卡壳 pj2187凸包 cogs896 bzoj2829 信用卡凸包莫比乌斯反演基础 bzoj 4173 zhao gui lv bzoj 3529 mobiwus bzoj 4407 mobiwus bzoj 2818 mobiw

棋盘覆盖问题

棋盘覆盖问题       问题描述: 在一个2^k×2^k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有4^k种情形.因而对任何k≥0,有4^k种不同的特殊棋盘.     下图–图(1)中的特殊棋盘是当k=3时16个特殊棋盘中的一个: 图(1) 题目要求在棋盘覆盖问题中,要用下图-图(2)所示的4种不同形态的L型骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖. 图(2) 题目

Q:opencv棋盘标定总是找不到角点

可能是:1.pattern_size没有设置正确(棋盘图片的内角点数目,指除去棋盘边缘的棋盘角点) 2.黑白格,彩格我试了一下不好用 3.内角点的行列数目设置,一定要大于2

计算机算法设计与分析之棋盘覆盖问题

一.引子 最近又重新上了算法课,现在想来有点汗颜,大学期间已经学习了一个学期,到现在却依然感觉只是把老师讲过的题目弄懂了,并没有学到算法的一些好的分析方法和思路,碰到一个新的问题后往往感觉很棘手,痛定思痛之后觉得还是好好再学习一遍,争取能理解透彻每种算法的思路和核心,同时也劝诫各位同行们做事要脚踏实地,不能应付老师的作业,最后吃亏的还是自己啊. 二.棋盘覆盖问题 在一个由2^k *2^k个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘 为一特殊棋盘.现有四种L型骨

棋盘的多米诺覆盖:Dimer Lattice Model,Pfaff 多项式,Kasteleyn 定理

这次来介绍计数组合学里面一个经典的问题:Dimer Lattice Model.问题是这样的:一个有 64 个方格的国际象棋棋盘,有多少种不同的多米诺骨牌覆盖?这里的覆盖是指不重复不遗漏地盖住整个棋盘. 下图是一种可能的覆盖方式(图片来自 Wiki 百科): 这个问题的答案是 12988816,非常大的一个数字,绝对不是一个一个数出来的.1961 年德国物理学家 Kasteleyn 借助于线性代数中的一个结论首先解决了这个问题,我们接下来就介绍他的方法. ~~~~~~~~~~~~~~~~~~~~