hdu 3658 How many words

简介: 点击打开hdu 3658 思路: 递推+矩阵快速幂 分析: 1 题目的意思是在52个英文字母里面选择m个字母组成一个字符串,满足以下两个条件。

点击打开hdu 3658

思路: 递推+矩阵快速幂

分析:

1 题目的意思是在52个英文字母里面选择m个字母组成一个字符串,满足以下两个条件。第一是相邻的两个字符的ASCLL码的绝对值小于等于32,第二至少要有一对的字符的绝对值为32

2 那么不考虑第二个条件的时候,我们可以求出所有的符合的个数。假设f(n)(j)表示的是前n个字符最后一个字符为j,那么我们可以求出所有满足第一个条件的所有个数。因为至少需要有一对相邻的字符的绝对值为32,那么我们只要把第一次求出的所有的个数减去“相邻的两个字符的ASCLL码的绝对值小于等于31”的即可

3 那么我们考虑“相邻的两个字符的ASCLL码的绝对值小于等于32”这种情况,f(n)(j) = Σ(f(n-1)(k)) , abs(j-k) <= 32

  那么我们可以构造出如下的矩阵

  

4 那么相邻的两个字符的ASCLL码的绝对值小于等于31就和上面的类似


代码:

/************************************************
 * By: chenguolin                               * 
 * Date: 2013-08-31                             *
 * Address: http://blog.csdn.net/chenguolinblog *
 ************************************************/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long int64;
const int MOD = 1e9+7;
const int N = 52; 

struct Matrix{
    int64 mat[N][N];
    Matrix operator*(const Matrix &m)const{
        Matrix tmp;
        for(int i = 0 ; i < N ; i++){
            for(int j = 0 ; j < N ; j++){
                tmp.mat[i][j] = 0;
                for(int k = 0 ; k < N ; k++)
                    tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;
                tmp.mat[i][j] %= MOD;
            }
        }
        return tmp;
    }
};

void init(Matrix &m1 , Matrix &m2){
    // m1
    memset(m1.mat , 0 , sizeof(m1.mat));
    int x = 25;
    for(int i = 0 ; i < 26 ; i++){
        x++;
        for(int j = 0 ; j <= x ; j++)
            m1.mat[i][j] = 1;
    }
    x = -1;
    for(int i = 26 ; i < N ; i++){
        x++;
        for(int j = x ; j < N ; j++)
            m1.mat[i][j] = 1;
    }
    // m2
    memset(m2.mat , 0 , sizeof(m2.mat));
    x = 24;
    for(int i = 0 ; i < 26 ; i++){
        x++;
        for(int j = 0 ; j <= x ; j++ )
            m2.mat[i][j] = 1;
    }
    x = 0;
    for(int i = 26 ; i < N ; i++){
        x++;
        for(int j = x ; j < N ; j++)
            m2.mat[i][j] = 1;
    }
}

int64 Pow(Matrix m , int n){
    Matrix ans;
    n--;
    memset(ans.mat , 0 , sizeof(ans.mat));
    for(int i = 0 ; i < N ; i++)
        ans.mat[i][i] = 1;
    while(n){
        if(n&1)
            ans = ans*m;
        n >>= 1;
        m = m*m;
    }
    int64 sum = 0;
    for(int i = 0 ; i < N ; i++){
        for(int j = 0 ; j < N ; j++){
            sum += ans.mat[i][j];
            sum %= MOD;
        }
    }
    return sum;
}

void solve(Matrix &m1 , Matrix &m2 , int n){
    int64 x = Pow(m1 , n);
    int64 y = Pow(m2 , n); 
    printf("%lld\n" , (x-y+MOD)%MOD);
}

int main(){
    int cas , n;
    Matrix m1 , m2;
    init(m1 , m2);
    scanf("%d" , &cas);
    while(cas--){
        scanf("%d" , &n);
        solve(m1 , m2 , n);
    }
    return 0;
}



目录
相关文章
|
Linux
CentOS 安装rz和sz命令
CentOS 安装rz和sz命令
344 0
|
iOS开发
iOS 逆向编程(十三)PS命令获取进程PID与名称(Process Status)
iOS 逆向编程(十三)PS命令获取进程PID与名称(Process Status)
437 0
|
机器学习/深度学习 存储 安全
隐语小课 | 基于秘密分享的混合比特数学运算库-SIRNN介绍
隐语小课 | 基于秘密分享的混合比特数学运算库-SIRNN介绍
619 0
|
算法 网络安全 数据安全/隐私保护
【密码学】手摸手带你手算AES
本文带着大家手动计算了一下完整的简化版AES的整个流程,其实主要都参考了密码学与网络安全这本书,大部分的公式都是从这本书上来的,我是真的喜欢这个例子,麻雀虽小,五脏俱全,用来学习AES的入门感觉非常的合适,如果能够完整的自己手算下来这个例子,然后再去看完整版的AES算法,会简单非常多,主要就是规模扩大了一下,核心的流程还是上面这一套。最后,感谢能看到这里的读者,如果本文对大佬们理解AES有一点点的帮助,也不枉我手动敲了这么多的公式和矩阵了。
1290 0
【密码学】手摸手带你手算AES
|
Java 持续交付 数据库
避免服务分层污水池反模式
【6月更文挑战第30天】本文介绍污水池反模式,分层架构在敏捷性、部署性和性能方面得分较低,但具有高测试性和易开发性。关键在于合理分层以降低耦合和提高解耦效果。
616 1
避免服务分层污水池反模式
|
12月前
|
前端开发 UED 开发者
React 日期选择器 Date Picker
本文从React的角度探讨了日期选择器的使用方法,包括使用`react-datepicker`库的基本配置、自定义样式、国际化设置、常见问题及解决方案,旨在帮助开发者构建用户友好的日期选择组件。
405 12
|
索引
利用滚动索引来管理海量Elasticsearch数据
利用滚动索引来管理海量Elasticsearch数据
330 3
|
SQL 存储 数据处理
Flink SQL 问题之提交程序运行报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
580 3
|
算法 API Python
使用 Python 对接阿里云 OpenAPI 自签名
使用 Python 对接阿里云 OpenAPI 自签名
786 1
|
运维 监控 安全
认识SOAR-安全事件编排自动化响应
SOAR是最近几年安全市场上最火热的词汇之一。SOAR究竟是什么,发展历程是什么,能够起什么作用,带着这些问题我们来认识一下SOAR。
1306 0
认识SOAR-安全事件编排自动化响应