ZOJ 3690

题意:

有n个人和m个数和一个k,如今每一个人能够选择一个数。假设相邻的两个人选择同样的数。那么这个数要大于k

求选择方案数。

思路:

打表推了非常久的公式都没推出来什么可行解,好不easy有了想法结果WA到天荒地老也无法AC。。

于是学习了下正规的做法,恍然大悟。

这道题应该用递推 + 矩阵高速幂。

我们设F(n) = 有n个人,第n个人选择的数大于k的方案数;

G(n) = 有n个人。第n个人选择的数小于等于k的方案数;

那么递推关系式即是:

F(1)=m−k,G(1)=k

F(n)=(m−k)∗F(n−1)+(m−k)∗G(n−1)

G(n)=k∗(n−1)+(k−1)∗G(n−1)

ans=F(n)+G(n)

变换矩阵例如以下:

(m−kkm−kk−1)∗(F(n−1)G(n−1))=(F(n)G(n))

代码君:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue> using namespace std; #define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL; const lint mod = 1e9 + 7;
const int maxn = 4;
lint n,m,k; struct Matrix{
int n , m ;
lint a[maxn][maxn];
Matrix( int n , int m ){
this->n = n ;
this->m = m ;
cls(a);
}
Matrix operator * ( const Matrix &tmp ){
Matrix res( n , tmp.m );
for( int i = 0 ; i < n ; i++ )
for( int j = 0 ; j < tmp.m ; j++ )
for( int k = 0 ; k < m ; k++ )
res.a[i][j] = ( res.a[i][j] + ( a[i][k] * tmp.a[k][j] ) % mod ) % mod;
return res;
}
}; void Matrix_print( Matrix x ){
for( int i = 0 ; i < x.n ; i++ ){
for( int j = 0 ; j < x.m ; j++){
cout << x.a[i][j] << ' ';
}
cout << endl;
}
cout << endl;
}
Matrix fast_pow( Matrix x , lint n ){
Matrix res( x.n , x.m );
for( int i = 0 ; i < x.n ; i++ ) res.a[i][i] = 1;
while( n ){
if( n & 1 )
res = res * x;
x = x * x;
n >>= 1;
}
return res;
} void solve(){
Matrix base( 2 , 1 );
Matrix fun( 2 , 2 );
fun.a[0][0] = m - k ;
fun.a[0][1] = m - k ;
fun.a[1][0] = k ;
fun.a[1][1] = k - 1 ;
base.a[0][0] = m - k ;
base.a[1][0] = k ;
fun = fast_pow( fun , n - 1);
base = fun * base ;
cout << (base.a[1][0] + base.a[0][0]) % mod << endl;
}
int main(){
// freopen("input.txt","r",stdin);
while(cin >> n >> m >> k){
solve();
}
return 0;
}

pid=3658">HDU 3658

题意:

在52个英文字母里面选择m个字母组成一个字符串。

满足下面两个条件:

一、相邻的两个字符的ASCLL码的绝对值小于等于32(比方说X与x的码值差为32)。

二、至少要有一对的字符的绝对值为32。

思路:

分两步:先求出满足条件一的方案数。再减去相邻的两个字符的ASCLL码的绝对值**小于**32的方案数即可。

第一步:

我们设Fc(n) = 有n个字符。第n个字符为c的满足条件一方案数;

那么

FA(n)=FA(n−1)+FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)

FB(n)=FA(n−1)+FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)

FC(n)=FA(n−1)+FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)



FZ(n)=FA(n−1)+FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)+...+Fz(n−1)

Fa(n)=FA(n−1)+FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)+...+Fz(n−1)

Fb(n)=FB(n−1)+FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)+...+Fz(n−1)

Fc(n)=FC(n−1)+...+FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)+...+Fz(n−1)



Fz(n)=FZ(n−1)+Fa(n−1)+Fb(n−1)+Fc(n−1)+...+Fz(n−1)

然后建立矩阵变换高速幂搞下即可。

。这个矩阵太庞大我就不画了。。

第二步:

我们设Gc(n) = 有n个字符,第n个字符为c的相邻的两个字符的ASCLL码的绝对值**小于**32的方案数。

那么

GA(n)=GA(n−1)+GB(n−1)+GC(n−1)+...+GZ(n−1)

GB(n)=GA(n−1)+GB(n−1)+GC(n−1)+...+GZ(n−1)+Ga(n−1)

GC(n)=GA(n−1)+GB(n−1)+GC(n−1)+...+GZ(n−1)+Ga(n−1)+Gb(n−1)



GZ(n)=GA(n−1)+GB(n−1)+GC(n−1)+...+GZ(n−1)+Ga(n−1)+Gb(n−1)+Gc(n−1)+...+Gy(n−1)

Ga(n)=GB(n−1)+GC(n−1)+...+GZ(n−1)+Ga(n−1)+Gb(n−1)+Gc(n−1)+...+Gz(n−1)

Gb(n)=GC(n−1)+...+GZ(n−1)+Ga(n−1)+Gb(n−1)+Gc(n−1)+...+Gz(n−1)



Gz(n)=Ga(n−1)+Gb(n−1)+Gc(n−1)+...+Gz(n−1)

建立变换矩阵,而后高速幂。

ans=∑i<=zi=AFi(n)−∑i<=zi=AGi(n)

代码君:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue> using namespace std; #define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL; const int maxn = 54 ;
const lint mod = 1e9 + 7;
lint n ; struct Matrix{
int n , m ;
lint a[maxn][maxn];
Matrix( int n , int m ){
this->n = n ;
this->m = m ;
cls(a);
}
Matrix operator * ( const Matrix &tmp ){
Matrix res( n , tmp.m );
for( int i = 0 ; i < n ; i++ )
for( int j = 0 ; j < tmp.m ; j++ )
for( int k = 0 ; k < m ; k++ )
res.a[i][j] = ( res.a[i][j] + ( a[i][k] * tmp.a[k][j] ) % mod ) % mod;
return res;
}
}; Matrix fast_pow( Matrix x , lint n ){
Matrix res( x.n , x.m );
for( int i = 0 ; i < x.m ; i++ ) res.a[i][i] = 1 ;
while( n ){
if( n & 1 )
res = res * x;
x = x * x ;
n >>= 1;
}
return res;
} void solve(){
if( n == 2 ){
cout << 52 << endl;
return;
}
Matrix base( 52 , 1 );
Matrix base1( 52 , 1 );
Matrix base2( 52 , 1 );
Matrix fun( 52 , 52 );
for( int i = 0 ; i < 52 ; i++ ) base.a[i][0] = 1;
for( int i = 0 ; i < 26 ; i++ ){
for( int j = 0 ; j < 27 + i ; j++ )
fun.a[i][j] = 1;
}
for( int i = 26 ; i < 52 ; i++ ){
for( int j = 51 ; j >= i - 26 ; j-- )
fun.a[i][j] = 1;
}
fun = fast_pow( fun , n - 1 );
base1 = fun * base ;
lint sum1 = 0;
cls(fun.a);
for( int i = 0 ; i < 52 ; i++ ) sum1 = ( sum1 + base1.a[i][0] ) % mod;
for( int i = 0 ; i < 26 ; i++ ){
for( int j = 0 ; j < 26 + i; j++ )
fun.a[i][j] = 1;
}
for( int i = 26 ; i < 52 ; i++ ){
for( int j = 51 ; j >= i - 25 ; j-- )
fun.a[i][j] = 1;
}
fun = fast_pow( fun , n - 1 );
base2 = fun * base ;
lint sum2 = 0;
for( int i = 0 ; i < 52 ; i++ ) sum2 = ( sum2 + base2.a[i][0] ) % mod;
lint ans = ( sum1 - sum2 + mod ) % mod ;
cout << ans << endl;
}
int main(){
//freopen("output.txt","w+",stdout);
int t ; cin >> t;
while( t-- ){
cin >> n ;
solve();
}
return 0;
}

ZOJ 3690 &amp; HDU 3658 (矩阵高速幂+公式递推)的更多相关文章

  1. HDU 1757 矩阵快速幂加速递推

    题意: 已知: 当x<10时:f(x)=x 否则:f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + --+ a9 * f(x-10); 求:f(x ...

  2. HDU - 2604 矩阵快速幂 字符串递推 两种解法

    记dp[i]为长度i且符合题意的方案数,dp[n]就是解 符合方案的是不含fmf和fff子串的字符串 考虑如何从前面几项递推出后面第i项 (★表示存在生成的非法方案)←其实没啥用处 i=1时 m③ f ...

  3. HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with ...

  4. CH 3401 - 石头游戏 - [矩阵快速幂加速递推]

    题目链接:传送门 描述石头游戏在一个 $n$ 行 $m$ 列 ($1 \le n,m \le 8$) 的网格上进行,每个格子对应一种操作序列,操作序列至多有 $10$ 种,分别用 $0 \sim 9$ ...

  5. hdu 2842(矩阵高速幂+递推)

    题意:一个中国环的游戏,规则是一个木棒上有n个环.第一个环是能够任意放上或拆下的,剩下的环x假设想放上或拆下必须前一个环x-1是放上的且前x-2个环所有是拆下的,问n个环最少多少次操作能够所有拆掉. ...

  6. CH3401 石头游戏(矩阵快速幂加速递推)

    题目链接:传送门 题目: 石头游戏 0x30「数学知识」例题 描述 石头游戏在一个 n 行 m 列 (≤n,m≤) 的网格上进行,每个格子对应一种操作序列,操作序列至多有10种,分别用0~9这10个数 ...

  7. HDU5950 Recursive sequence (矩阵快速幂加速递推) (2016ACM/ICPC亚洲赛区沈阳站 Problem C)

    题目链接:传送门 题目: Recursive sequence Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total ...

  8. BZOJ4547 Hdu5171 小奇的集合 【矩阵快速幂优化递推】

    BZOJ4547 Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个 ...

  9. [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)

    Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...

随机推荐

  1. poj_2828线段树,逆序插入

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #d ...

  2. poj_2777线段树+位运算

    第一次没想到用位运算,不出意料的T了,,, PS:在床上呆了接近两个月后,我胡汉三又杀回来刷题啦-- #include<iostream> #include<cstdio> # ...

  3. Clion远程开发

    2018.3 开始Clion可以支持远程开发了   官网教程如下: https://www.jetbrains.com/help/clion/remote-projects-support.html ...

  4. childNodes.length和form.length的不同

    我们知道,DOM里面提供了element.childNodes.length属性,childNodes 属性返回节点的子节点集合,以 NodeList 对象. 那么childNodes包含哪些节点呢? ...

  5. Python多版本情况下四种快速进入交互式命令行的操作技巧

    因为工作需求或者学习需要等原因,部分小伙伴的电脑中同时安装了Python2和Python3,相信在Python多版本的切换中常常会遇到Python傻傻分不清楚的情况,今天小编整理了四个操作技巧,以帮助 ...

  6. How Javascript works (Javascript工作原理) (十四) 解析,语法抽象树及最小化解析时间的 5 条小技巧

    个人总结:读完这篇文章需要15分钟,文章介绍了抽象语法树与js引擎解析这些语法树的过程,提到了懒解析——即转换为AST的过程中不直接进入函数体解析,当这个函数体需要执行的时候才进行相应转换.(因为有的 ...

  7. 洛谷 P1952 火星上的加法运算_NOI导刊2009提高(3)

    P1952 火星上的加法运算_NOI导刊2009提高(3) 题目描述 最近欢欢看到一本有关火星的书籍,其中她被一个加法运算所困惑,由于她的运算水平有限.她想向你求助,作为一位优秀的程序员,你当然不会拒 ...

  8. [Python] Indexing An Array With Another Array with numpy

    NumPy Reference: Indexing Integer array indexing: Select array elements with another array def index ...

  9. C#做的CPU内存使用率

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  10. Mesh BRep Shapes

    Mesh BRep Shapes eryar@163.com Abstract. 当对OpenCASCADE的BRep表示法的数据结构有了一定的理解后,建议可以自己实现一个显示数据生成的功能,即网格剖 ...