zoukankan      html  css  js  c++  java
  • Choosing number ZOJ 3690 (矩阵快速幂)

    题意:n个人站成一排,每个人任意从1——m中任意取一个数,要求相邻两个人的如果数字相同,数字要大于k。

    分划思想推导表达式:

    假设  i  个人时。第i个人的选择有两种一种是选择小于等于k的数,另一种是大于k的数。则设这两种情况的组合数分别为F(i)和 G(i)

    那么F(i)=(m-k)(F(i-1)+G(i-1));m-k表示第i个人,选择了大于k的选择。

    那么G(i)=kF(i-1)+(k-1)G(i-1);  k*F(i-1),表示第i个人选的是大于k的数,而第i个人只能在0—k种选择,所以0—k都可以选择。但是,如果第i-1人选择了

    0—k中的一个数,那么为了满足条件相邻元素大于k的原则,所以不能选择第i-1的数,所以是k-1;

    然后就是基础的构造函数了。

    #include<cstdio>
    #include<cstring>
    #define mod int(1e9+7)
    #define ll long long
    ll m, k, n;
    struct jz
    {
        ll num[2][2];
        jz(){ memset(num, 0, sizeof(num)); }
        jz operator*(const jz &p)const
        {
            jz ans;
            for (int k = 0; k < 2;++k)
            for (int i = 0; i < 2;++i)
            for (int j = 0; j < 2; ++j)
                ans.num[i][j] = (ans.num[i][j] + num[i][k] * p.num[k][j] % mod) % mod;
            return ans;
        }
    }p;
    jz POW(jz x, ll n)
    {
        jz ans;
        for (int i = 0; i < 2; ++i)ans.num[i][i] = 1;
        for (; n;n>>=1, x=x*x)
        if (n & 1)ans = ans*x;
        return ans;
    }
    void init()
    {
            p.num[0][0] = m - k; p.num[0][1] = m - k;
            p.num[1][0] = k; p.num[1][1] = k - 1;
    }
    int main()
    {
        while (scanf("%lld%lld%lld", &n, &m, &k)!=EOF)
        {
            ll G1 = k;
            ll F1 = m - k;
                init();
                jz ans = POW(p, n - 1);
                printf("%lld\n", (ans.num[0][0] * F1%mod + ans.num[0][1] * G1%mod+ans.num[1][0]*F1%mod+ans.num[1][1]*G1%mod) % mod);
        }
        return 0;
    }
  • 相关阅读:
    小程序---云开发----云函数
    小程序的基本概念-生命周期(组件 wxml)
    小程序的基本概念
    vue登录功能和将商品添加至购物车实现
    vue脚手架创建项目
    node.js评论列表和添加购物车数据库表创建
    学习脚手架--组件之间跳转与参数(组件之间参数)
    node.js 需要注意知识点
    如何查询小程序官方手册
    vue ui九宫格、底部导航、新闻列表、跨域访问
  • 原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/9502179.html
Copyright © 2011-2022 走看看