zoukankan      html  css  js  c++  java
  • P1357 花园 状压 矩阵快速幂

    题意

    小L有一座环形花园,沿花园的顺时针方向,他把各个花圃编号为1~N(2<=N<=10^15)。他的环形花园每天都会换一个新花样,但他的花园都不外乎一个规则,任意相邻M(2<=M<=5,M<=N)个花圃中有不超过K(1<=K<M)个C形的花圃,其余花圃均为P形的花圃。

    例如,N=10,M=5,K=3。则

    CCPCPPPPCC 是一种不符合规则的花圃;

    CCPPPPCPCP 是一种符合规则的花圃。

    请帮小L求出符合规则的花园种数Mod 1000000007

    由于请您编写一个程序解决此题。

    思路:

      可以枚举前m位的状态,然后求出合法递推的可能。由于合法递推的情况是固定的,所以我们可以把这些情况放入矩阵中,跑n次矩阵快速幂。因为这道题是一个环,所以结果中跑一个周期的就是答案,就是【i】【i】的情况。

    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    
    using namespace std;
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    
    
    typedef long long ll;
    typedef unsigned long long ull;
    //typedef __int128 bll;
    typedef pair<ll ,ll > pll;
    typedef pair<int ,int > pii;
    typedef pair<int,pii> p3;
    
    //priority_queue<int> q;//这是一个大根堆q
    //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
    #define fi first
    #define se second
    //#define endl '
    '
    
    #define OKC ios::sync_with_stdio(false);cin.tie(0)
    #define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
    #define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
    #define max3(a,b,c) max(max(a,b), c);
    #define min3(a,b,c) min(min(a,b), c);
    //priority_queue<int ,vector<int>, greater<int> >que;
    
    const ll mos = 0x7FFFFFFF;  //2147483647
    const ll nmos = 0x80000000;  //-2147483648
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f; //18
    const int mod = 1000000007;
    const double esp = 1e-8;
    const double PI=acos(-1.0);
    const double PHI=0.61803399;    //黄金分割点
    const double tPHI=0.38196601;
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    /*-----------------------showtime----------------------*/
    
                const int maxn = 40;
                ll n,m,k;
                struct matrix
                {
                    ll a[maxn][maxn];
                    matrix(){
                        memset(a, 0, sizeof(a));
                    }
                }mp;
                int ji[maxn];
    
                matrix mul(matrix A, matrix B){
                    int l = (1 << m) - 1;
                    matrix res;
    
                    for(int i=0; i<=l; i++){
                        for(int j=0; j<=l; j++){
                            for(int k=0; k <= l; k++)
                                res.a[i][j] = (res.a[i][j] + A.a[i][k] * B.a[k][j] % mod)%mod;
                        }
                    }
                    return res;
                }
    
                matrix ksm(matrix A, ll n){
                    matrix res;
                    int l = (1 << m) - 1;
                    for(int i=0; i<=l; i++) res.a[i][i] = 1;
    
                    while(n > 0){
                        if(n & 1) res = mul(res, A);
                        A = mul(A, A);
                        n >>= 1;
                    }
                    return res;
                } 
    int main(){
                cin>>n>>m>>k;
    
                for(int i=0; i<(1<<m); i++) ji[i] = __builtin_popcount(i);
    
                for(int i=0; i<(1<<m); i++) if(ji[i] <= k){
    
                    int t1 = (i>>1) | (1 << (m-1));
                    int t2 = (i>>1);
                    if(ji[t1] <= k) mp.a[i][t1] = 1;
                    mp.a[i][t2] = 1;
                }
    
                mp = ksm(mp, n);
    
                ll ans = 0;
                for(int i=0; i<(1<<m); i++){
                    ans = (ans + mp.a[i][i]) % mod;
                }
                cout<<ans<<endl;
                return 0;
    }
    View Code
  • 相关阅读:
    leetcode1046
    leetcode1041
    leetcode1042
    leetcode399
    【经验分享】数据科学与机器学习面试指南
    计算机视觉计算任务有哪些,怎么分类 ?
    超详细!上线一个机器学习项目你需要哪些准备?
    人工智能和机器学习的前世今生
    机器学习从业人员到底做什么?
    两年AI研究经验(教训)总结,进来看看吧!
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/10346234.html
Copyright © 2011-2022 走看看