zoj3690--Choosing number(dp,矩阵快速幂)

来源:互联网 发布:搜索引擎算法 知乎 编辑:程序博客网 时间:2024/05/20 18:15

 Choosing number
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu
Submit Status

Description

There are n people standing in a row. And There are m numbers, 1.2...m. Every one should choose a number. But if two persons standing adjacent to each other choose the same number, the number shouldn't equal or less than k. Apart from this rule, there are no more limiting conditions.

And you need to calculate how many ways they can choose the numbers obeying the rule.

Input

There are multiple test cases. Each case contain a line, containing three integer n (2 ≤ n ≤ 108), m (2 ≤ m ≤ 30000), k(0 ≤ k ≤ m).

Output

One line for each case. The number of ways module 1000000007.

Sample Input

4 4 1

Sample Output

216

题意:n个人每个人在m个数中选一个,要求相邻的人如果数字相同,那么数字要大于k,问有多少种选法

dp[i][0] 代表有i个人时 且最后一个人选的数小于等于k的种数

dp[i][0] 代表有i个人时 且最后一个人选的数大于k的种数

用矩阵快速幂的优化和http://blog.csdn.net/winddreams/article/details/42805891相同


#include <cstdio>#include <cstring>#include <algorithm>using namespace std ;#define LL long long#define MOD 1000000007struct node{    LL a[5][5] ;    int n ;};node mul(node p,node q){    int i , j , k ;    node s ;    s.n = p.n ;    for(i = 0 ; i < p.n ; i++)        for(j = 0 ; j < p.n ; j++)        {            s.a[i][j] = 0 ;            for(k = 0; k < p.n ; k++)                s.a[i][j] = ( s.a[i][j] + p.a[i][k]*q.a[k][j] ) % MOD ;        }    return s ;}node pow(node p,int k){    if( k == 1 )        return p ;    node s = pow(p,k/2) ;    s = mul(s,s) ;    if( k%2 )        s = mul(s,p) ;    return s ;}int main(){    LL n , m ,  k , ans ;    int i , j ;    node p , s ;    while( scanf("%lld %lld %lld", &n, &m, &k) != EOF )    {        ans = 0 ;        p.n = 2;        p.a[0][0] = k-1 ; p.a[0][1] = k ;        p.a[1][0] = m-k ; p.a[1][1] = m-k ;        s = pow(p,n-1) ;        ans = ( ans + s.a[0][0]*k + s.a[1][0]*k ) % MOD ;        ans = ( ans + s.a[0][1]*(m-k) + s.a[1][1]*(m-k) ) % MOD ;        printf("%lld\n", ans) ;    }    return 0;}


0 0