ZOJ3690—Choosing number

题目链接:https://vjudge.net/problem/ZOJ-3690

题目意思: 有n个人,每个人可以从m个数中选取其中的一个数,而且如果两个相邻的数相同,则这个数大于等于k,问这样的数一共有多少种选择,结果取模。

思路:可能是算递推式子的能力还不够吧?没有推出来。这里我们我们运用划分的思想定义F[i]表示有i个人且最后一个人选的数组大于k选择数量,G[i]表示有i个人且最后一个人选的数组小于等于k的数量。

我们可以得到以下递推式子:

F[i]=(m-k)*(F[i-1]+G[i-1]),注:第i个人选择的数大于k,当然是i-1个人最后一个人选择的数大于k和最后一个人小于等于k的数量之和乘以大于k的数的数量,因为第i个人选择的是大于k的数,所以不被题目的限制条件限制。

G[i]=k*F[i-1]+(k-1)*G[i-1],注:第i个人选择的数小于等于k,当然是i-1个人最后一个人选择大于k的数量乘以k加上i-1个人最后一个人选择小于等于k,为了让相邻的选择不同,所以乘以(k-1)。

答案就是G[n]+F[n]。

算递推式子的时候,看到这种以某个数k为限制的时候,应该以k为划分去思考问题。对今后算递推式子也算有点启发吧。

代码:(有了递推式子以后代码就很简单了,套路的矩阵快速幂)

 1 //Author: xiaowuga
 2 #include <bits/stdc++.h>
 3 #define maxx INT_MAX
 4 #define minn INT_MIN
 5 #define inf 0x3f3f3f3f
 6 #define size 2
 7 #define MOD 1000000007
 8 using namespace std;
 9 typedef long long ll;
10 ll a,b,c;
11 struct Matrix{
12     ll mat[3][3];
13     void clear(){
14         memset(mat,0,sizeof(mat));
15     }
16     Matrix operator * (const Matrix & m) const{
17         Matrix tmp;
18         for(int i=0;i<size;i++)
19             for(int j=0;j<size;j++){
20                 tmp.mat[i][j]=0;
21                 for(int k=0;k<size;k++){
22                     tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
23                     tmp.mat[i][j]%=MOD;
24                 }
25             }
26         return tmp;
27     }
28 };
29 Matrix POW(Matrix m,ll k){
30     Matrix ans;
31     ans.clear();
32     for(int i=0;i<size;i++) ans.mat[i][i]=1;
33     while(k){
34         if(k&1) ans=ans*m;
35         k/=2;
36         m=m*m;
37     }
38     return ans;
39 }
40 int main() {
41     ios::sync_with_stdio(false);cin.tie(0);
42     while(cin>>a>>b>>c){
43         Matrix m;
44         m.clear();
45         m.mat[0][0]=m.mat[0][1]=b-c;
46         m.mat[1][0]=c;m.mat[1][1]=c-1;
47         Matrix ans=POW(m,a-1);
48         ll ans1=0,ans2=0;
49         ans1=((ans.mat[0][0]*(b-c))%MOD+(ans.mat[0][1]*c)%MOD)%MOD;
50         ans2=((ans.mat[1][0]*(b-c))%MOD+(ans.mat[1][1]*c)%MOD)%MOD;
51         cout<<(ans1+ans2)%MOD<<endl;
52     }
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/xiaowuga/p/7356268.html