ZOJ 3690 Choosing number

原创 2015年07月08日 09:34:51

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;
}





ZOJ 3690 Choosing number

#include #include #include #include #include #include using namespace std; #define LL long l...
  • u011555705
  • u011555705
  • 2013年11月07日 22:20
  • 328

zoj 3690 Choosing number

点击打开zoj 3690 思路: dp+矩阵快速幂 分析; 1 题目的意思是有n个人和m个数和一个k,现在每个人可以选择一个数,但是要求如果相邻的两个人选择相同的数,那么这个数要大于k 2 假设F(n...
  • cgl1079743846
  • cgl1079743846
  • 2013年08月26日 19:11
  • 1144

【矩阵快速幂】ZOJ 3690 Choosing number

矩阵快速幂。。。顾名思义就是利用矩阵的结合律来进行快速幂运算。。。嘛,笔者也是做这道题两小时前把矩阵快速幂搞明白了的。。。所以其实还不熟= = 题目地址:http://acm.zju.edu...
  • q79186954
  • q79186954
  • 2015年07月11日 18:54
  • 196

ZOJ 3690 Choosing number(矩阵快速幂)

题目地址:ZOJ 3690 假设F(n)表示前n个人第n个人选择的数大于k的个数,G(n)表示的是前n个人第n个人选择的数小于等于k的个数    那么F(n) = F(n-1)*(m-k)+G(n...
  • u013013910
  • u013013910
  • 2014年09月27日 21:49
  • 777

【ZOJ 3690】 Choosing number (矩阵快速幂)

【ZOJ 3690】 Choosing number (矩阵快速幂) Choosing number Time Limit: 2 Seconds      Memory Limit: 6553...
  • ChallengerRumble
  • ChallengerRumble
  • 2015年10月27日 20:02
  • 1474

ZOJ - 3690 Choosing number 矩阵快速幂

题目大意:有n个人排成一行,有m个数字,每个人可以选择1 – m的任一个数字,但有一个限制,如果相邻的两个人选择相同的数字的话,这个数字必须大于k 问有多少种选择方法解题思路:变化矩阵为(m-k, ...
  • L123012013048
  • L123012013048
  • 2015年05月30日 18:30
  • 345

zoj 3690 Choosing number 递推+矩阵快速幂

#include #include #define mod 1000000007 struct matrix { long long a[3][3]; }e,f; matrix mult...
  • a601025382s
  • a601025382s
  • 2013年03月31日 15:10
  • 1167

zoj 3690 Choosing number(矩阵乘法+dp)

题意:有n个人,每个人从1~m选一个数,但是相邻的人如果选了一样的数,那么这个数要大于k,问所有的选法。 思路:首先用dp[i][j]表示前i个人,第i个人选了第j个数字,那么 dp[i][j]=...
  • qian99
  • qian99
  • 2014年03月12日 20:07
  • 667

ZOJ 3690 Choosing number(dp矩阵优化)

Choosing number Time Limit: 2 Seconds      Memory Limit: 65536 KB There are n people standin...
  • acm_BaiHuzi
  • acm_BaiHuzi
  • 2015年08月17日 01:55
  • 480

zoj 3175 Number of Containers(数论~)

算是数论吧。 = = 就是求i从1到n的 n/i-1的累和。 开始我用最简单的累和,算20Y要好几秒,肯定过不去,也想了到n的平方根,思路是对的,可是没想明白 = =就去看别人题解了,破习惯。 结果人...
  • zxy_snow
  • zxy_snow
  • 2011年01月23日 18:38
  • 1774
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZOJ 3690 Choosing number
举报原因:
原因补充:

(最多只允许输入30个字)