zoukankan      html  css  js  c++  java
  • P1357 花园 (矩阵快速幂+ DP)

    题意:一个只含字母C和P的环形串

       求长度为n且每m个连续字符不含有超过k个C的方案数 

       m <= 5  n <= 1e15

    题解:用一个m位二进制表示状态 转移很好想

       但是这个题是用矩阵快速幂加速dp的 因为每一位的转移都是一样的

       用一个矩阵表示状态i能否转移到状态j 然后跑一遍

       统计答案特别讲究 因为是一个环 从1 ~ n+m

       那么 m+1 ~ n + m之间就是我们所求的 1 ~ m和n+1 ~ n + m是同样的一段

       就相当于把m位二进制状态 转移n次

       然后再转移到自己的就是答案

       初试模板题

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod = 1e9 + 7;
    
    ll n, m, k, len;
    struct node {
        ll c[64][64];
    }re, x;
    
    bool check(int x) {
        int cnt = 0;
        while(x) {
            if(x & 1) cnt++;
            x >>= 1;
        }
        if(cnt > k) return false;
        return true;
    }
    
    node mul(node a, node b) {
        node res;
        memset(res.c, 0, sizeof(res.c));
    
        for(int i = 0; i < len; i++)
        for(int j = 0; j < len; j++)
        for(int k = 0; k < len; k++)
            res.c[i][j] = (res.c[i][j] + a.c[i][k] * b.c[k][j] % mod) % mod;
        return res;
    }
    
    node pow_mod(node x, ll y) {
        node res;
        for(int i = 0; i < len; i++) res.c[i][i] = 1;
    
        while(y) {
            if(y & 1) res = mul(res, x);
            x = mul(x, x);
            y >>= 1;
        }
        return res;
    }
    
    int main() {
        scanf("%lld%lld%lld", &n, &m, &k);
        len = (1 << m);
        for(int i = 0; i < len; i++)
        for(int j = 0; j < len; j++)
            x.c[i][j] = 0;
    
        for(int i = 0; i < len; i++) {
            if(!check(i)) continue;
            int tmp = i;
            int ctmp = 1 << (m - 1);
            if((tmp & ctmp) == ctmp) tmp -= ctmp;
            tmp <<= 1;
            if(check(tmp)) x.c[i][tmp] = 1;
            tmp |= 1;
            if(check(tmp)) x.c[i][tmp] = 1;
        }
        re = pow_mod(x, n);
    
        ll ans = 0;
        for(int i = 0; i < len; i++) {
            if(check(i)) {
                ans += re.c[i][i];
                ans %= mod;
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    用Rails.5.2+ Vue.js做 vue-todolist app
    vue-router
    Vue.js教程--基础2(事件处理 表单输入绑定
    Vue组件(知识)
    Vue.js教程--基础(实例 模版语法template computed, watch v-if, v-show v-for, 一个组件的v-for.)
    ActiveRecord Nested Atrributes 关联记录,对嵌套属性进行CURD
    (GoRails) 自动侦测用户的时区,使用javascript 的jszt库。
    (GoRails) 如何去掉form输入框头尾的空格;何时用callbacks,gem;
    JQ each
    JQ 更改li 颜色
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11080597.html
Copyright © 2011-2022 走看看