BNUOJ28891 Choosing number(矩阵快速幂)

来源:互联网 发布:电路仿真软件哪种好 编辑:程序博客网 时间:2024/06/06 03:24

题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=28891

题意:

有n个人 选择m个数; 每个人可以任意选数 , 若2个相邻的人选择相同的数,当且仅当这个数大于k; 问总共有多少种方法选择数

分析:

对于这道题, 比赛的时候完全没想法, 怎么也没想到是矩阵快速幂;看了别人的博库之后, 仔细想想之后,好像只能用快速幂来做题, 问什么呢? 因为这道题数据很大,普通的方法遍历一次就已经超时了。 搜索更不可能;dp也是遍历的,也是不行。 对于数据很大的我们可以用快速幂来做,以节省时间。 但是普通的快速幂根本没法用。 所以我们看这道题之后, 只找规律了。

对于第一个人, 我们设 x0为选的数不超过k的方法的有几种,设x1为选的数超过k的方法的有几种; 

那么对于第二个人来说; y0 = x0*(k-1)+x2*k; y1= x0*(m-k)+x1*(m-k);

在我们找到这个规律之后, 我们就可以很清楚明白用矩阵快速幂了。

下面就是要够造的矩阵

       (y0, y1)= (x0, x1)    (k-1, m-k)

   (k,   m-k)

做了这道题, 我又复习了一遍矩阵快速幂; 同时我发现在矩阵乘法中矩阵的顺序对结果是有影响的,就是矩阵乘法中相乘矩阵的位置不能颠倒(自己可以想想为什么)。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int mod = 1000000007;const int N = 2;struct Node{    int row, cal;    long long s[N][N];    Node()    {        row = cal = N;        s[0][0] = 1, s[0][1] = 0;        s[1][0] = 0, s[1][1] = 1;    }};Node Matble(Node a, Node b){    Node ans;    ans.row = a.row;    ans.cal = b.cal;    for(int i = 0; i < ans.row; i++)        for(int j = 0; j < ans.cal; j++)            ans.s[i][j] = 0;    for(int i = 0; i < ans.row; i++)    {        for(int j = 0; j < ans.cal; j++)        {            for(int k = 0; k < a.cal; k++)                ans.s[i][j] = (ans.s[i][j] + a.s[i][k]*b.s[k][j]%mod)%mod;        }    }    return ans;}long long pow_Matble(int n, int m, int k){    Node ans, temp, res;    temp.s[0][0] = k-1, temp.s[0][1] = m-k;    temp.s[1][0] = k, temp.s[1][1] = m-k;    while(n)    {        if(n&1)            ans = Matble(ans, temp);        temp = Matble(temp, temp);        n >>= 1;    }    temp.s[0][0] = k, temp.s[0][1] = m-k;    temp.s[1][0] = 0, temp.s[1][1] = 0;    res = Matble(temp, ans);    long long sum = 0;    for(int i = 0; i < res.cal; i++)        sum =(sum + res.s[0][i])%mod;    return sum;}int main(){    int n, m, k;    while(scanf("%d%d%d", &n, &m, &k) != EOF)    {        long long ans = pow_Matble(n-1, m, k);        printf("%lld\n", ans);    }    return 0;}


0 0
原创粉丝点击