bnuoj 34985 Elegant String

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985

We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,…, k".

Let function(n, k) be the number of elegant strings of length n which only contains digits from 0 to k (inclusive). Please calculate function(n, k).

INPUT

Input starts with an integer T (T ≤ 400), denoting the number of test cases.

Each case contains two integers, n and k. n (1 ≤ n ≤ 1018) represents the length of the strings, and k (1 ≤ k ≤ 9) represents the biggest digit in the string

2

1 1

7 6

OUTPUT

For each case, first output the case number as "Case #x: ", and x is the case number. Then output function(n, k) mod 20140518 in this case.

Case #1: 2

Case #2: 818503

source:2014 ACM-ICPC Beijing Invitational Programming Contest

题意:首先定义一个串elegant string:在这个串里的任何子串都没有包括0~k的一个全排列,现在给出n和k,要求求出长度为n的elegant string的个数。

解法:DP+矩阵快速幂。我们先用DP推出递推公式,然后用矩阵快速幂解决这个公式。具体思想如下:

定义DP数组:dp[12][12](dp[i][j]表示长度为 i 时字符串末尾连续有 j 个不同数字,例:1233末尾只有一个数字3,2234末尾有3个:2,3,4)。

以第二组数据为例:n=7   k=6

初始化:dp[1][1]=k+1,dp[1][2,,,k]=0;

dp[i+1][1]=dp[i][1]+dp[i][2]+dp[i][3]+dp[i][4]+dp[i][5]+dp[i][6]

dp[i+1][2]=6*dp[i][1]+dp[i][2]+dp[i][3]+dp[i][4]+dp[i][5]+dp[i][6]

dp[i+1][3]=5*dp[i][2]+dp[i][3]+dp[i][4]+dp[i][5]+dp[i][6]

dp[i+1][4]=4*dp[i][3]+dp[i][4]+dp[i][5]+dp[i][6]

dp[i+1][5]=3*dp[i][4]+dp[i][5]+dp[i][6]

dp[i+1][6]=2*dp[i][5]+dp[i][6]

把递推式改为如下矩阵:

然后我们就可以用快速幂来解决了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define inf 0x7fffffff
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn=12;
11 const ll mod=20140518;
12
13 ll n,k;
14 struct matrix
15 {
16     ll an[maxn][maxn];
17 }A,B;
18 matrix multiply(matrix x,matrix y)
19 {
20     matrix sum;
21     memset(sum.an,0,sizeof(sum.an));
22     for (int i=1 ;i<=k ;i++)
23     {
24         for (int j=1 ;j<=k ;j++)
25         {
26             for (int k2=1 ;k2<=k ;k2++) {
27                 sum.an[i][j]=(sum.an[i][j]+x.an[i][k2]*y.an[k2][j]%mod);
28                 if (sum.an[i][j]>=mod) sum.an[i][j] -= mod;
29             }
30         }
31     }
32     return sum;
33 }
34 matrix power(ll K,matrix q)
35 {
36     matrix temp;
37     for (int i=1 ;i<=k ;i++)
38     {
39         for (int j=1 ;j<=k ;j++)
40         temp.an[i][j]= i==j ;
41     }
42     while (K)
43     {
44         if (K&1) temp=multiply(temp,q);
45         q=multiply(q,q);
46         K >>= 1;
47     }
48     return temp;
49 }
50 int main()
51 {
52     int t,ncase=1;
53     scanf("%d",&t);
54     while (t--)
55     {
56         scanf("%lld%lld",&n,&k);
57         if (n==1)
58         {
59             printf("Case #%d: %d\n",ncase++,k+1);continue;
60         }
61         matrix q;
62         for (int i=1 ;i<=k ;i++)
63         {
64             for (int j=1 ;j<=k ;j++)
65             {
66                 if (j>=i) q.an[i][j]=(ll)1;
67                 else if (j==i-1) q.an[i][j]=(ll)(k+2-i);
68                 else q.an[i][j]=(ll)0;
69             }
70         }
71         q=power(n-1,q);
72 //        for (int i=1 ;i<=k ;i++)
73 //        {
74 //            for (int j=1 ;j<=k ;j++)
75 //            cout<<q.an[i][j]<<" ";
76 //            cout<<endl;
77 //        }
78         ll ans=0;
79         for (int i=1 ;i<=k ;i++)
80         {
81             ans=(ans+(ll)q.an[i][1]*(ll)(k+1))%mod;
82         }
83         printf("Case #%d: %lld\n",ncase++,ans);
84     }
85     return 0;
86 }

后续:感谢提出宝贵的意见。。。。

时间: 2024-09-29 04:05:07

bnuoj 34985 Elegant String的相关文章

BNUOJ 34985 Elegant String 2014北京邀请赛E题 动态规划 矩阵快速幂

Elegant String Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k

BNUOJ 34985 Elegant String 2014北京邀请赛E题 矩阵快速幂

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 题目大意:问n长度的串用0~k的数字去填,有多少个串保证任意子串中不包含0~k的某一个全排列 邀请赛上A的较多的一道题,比赛的时候死活想不出,回来之后突然就想通了,简直..... = =! 解题思路: 对于所有串我们都只考虑末尾最多有多少位能构成全排列的一部分(用l来表示),即最多有多少位不重复的数字出现,将问题转化为求末尾最多有k位能构成全排列的串的总数量 假设k为5,有一个

bnu 34985 Elegant String(矩阵快速幂+dp推导公式)

Elegant String Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None Graph Theory      2-SAT     Articulation/Bridge/Biconnected Component      Cy

bnu oj 34985 Elegant String (矩阵+dp)

Elegant String We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k". Let function(n, k) be the number of elegant strings of length n which only contains digits

北邀 E Elegant String

E. Elegant String Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Submit Status PID: 34985 Font Size: + - We define a kind of strings as elegant string: among all the substrin

bnu 34895 Elegant String(矩阵快速幂)

题目链接:bnu 34895 Elegant String 题目大意:给定n和k,表示有一个长度为n的序列,序列中的元素由0~k组成,问说有多少个串满足不包含0~k的全排列. 解题思路:矩阵快速幂,根据dp[i][j]表示说第i为有j个相同,写出递推式,根据递推式求出矩阵. #include <cstdio> #include <cstring> typedef long long ll; const ll MOD = 20140518; const int N = 20; str

BNUOJ 34990 Justice String

Justice String Time Limit: 2000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Given two strings A and B, your task is to find a substring of A called justice string, which has the same length as B, and only has at

2014 北京邀请赛ABDHJ题解

A. A Matrix 点击打开链接 构造,结论是从第一行开始往下产生一条曲线,使得这条区间最长且从上到下递减, #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <stdio.h> #include <vector> #include <set> using namespace std; #defi

2014 BNU 邀请赛E题(递推+矩阵快速幂)

Elegant String 题意:给定一个字符串,由0-k数字组成,要求该串中,子串不包含0-k全排列的方案数 思路:dp[i][j]表示放到i个数字,后面有j个不相同,然后想递推式,大概就是对应每种情况k分别能由那几种状态转移过来,在纸上画画就能构造出矩阵了,由于n很大,所以用快速幂解决 代码: #include <stdio.h> #include <string.h> const long long MOD = 20140518; int t; long long n; i