zoukankan      html  css  js  c++  java
  • ZOJ 3690 Choosing number

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





  • 相关阅读:
    洛谷1280 尼克的任务
    洛谷1140 相似基因
    洛谷1133 教主的花园
    洛谷1130 红牌
    洛谷1122 最大子树和
    洛谷1103 书本整理
    洛谷1077 摆花
    【数学】数学知识习题小结(模板)
    python中的深拷贝和浅拷贝(面试题二)
    python中的深拷贝和浅拷贝(面试题)
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7123473.html
Copyright © 2011-2022 走看看