关闭

ZOJ 3690 Choosing number

453人阅读 评论(0) 收藏 举报
分类:

Choosing number

Time Limit: 2 Seconds      Memory Limit: 65536 KB

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个数字,现在N个人站成一排,每个人都编个号,如果相邻两个人编号相同,那么他们只能在k+1到M中选择数字,问有多少种不同的选择方法。

思路:首先,利用DP推到出递推式,由于N 很大,所以可以用矩阵快速幂来优化一下。

f[i][0]表示第i个人,在1到k之间选择一个数,f[i][1]表示第i个人在k+1到m之间选择一个数。此时前i个人共有f[i][0]+f[i][1]种方法

f[i][0]=f[i-1][0]*(k-1)+f[i-1][1]*k

f[i][1]=f[i-1][0](m-k)+f[i-1][1]*(m-k)


f[1][0]=k,f[1][1]=m-k;


ans=f[i][0]+f[i][1]

ans=(f[1][0],f[1][1]) |k-1,m-k|^(n-1)

                                 |k,   m-k|

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
typedef long long ll;
const ll mod=1e9+7;

using namespace std;

struct matrix
{
    ll f[2][2];
};

matrix mul(matrix a,matrix b)//矩阵乘法
{
    matrix c;
    memset(c.f,0,sizeof c.f);

    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            for(int k=0;k<2;k++)
            {
                c.f[i][j]=(c.f[i][j]+a.f[i][k]*b.f[k][j])%mod;
            }
        }
    }
    return c;
}

matrix fun(matrix a,ll n)//快速幂
{
    matrix s;
    s.f[0][0]=1;s.f[1][1]=1;
    s.f[0][1]=0;s.f[1][0]=0;

    while(n)
    {
        if(n&1)
        s=mul(s,a);
        a=mul(a,a);
        n=n>>1;
    }
    return s;
}

int main()
{
    ll n,k,m;
    while(cin>>n>>m>>k)
    {
        matrix e;
        e.f[0][0]=k-1;e.f[1][1]=m-k;
        e.f[0][1]=m-k;e.f[1][0]=k;
        e=fun(e,n-1);
        ll ans;
        ans=( k*e.f[0][0]+(m-k)*e.f[1][0]+k*e.f[0][1]+(m-k)*e.f[1][1] )%mod;

        cout<<ans<<endl;

    }
    return 0;
}





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:120000次
    • 积分:3498
    • 等级:
    • 排名:第9871名
    • 原创:236篇
    • 转载:9篇
    • 译文:0篇
    • 评论:8条
    文章分类
    最新评论