swust oj 715--字典序问题(组合数预处理)

题目链接:http://acm.swust.edu.cn/problem/715/

Time limit(ms): 1000      Memory limit(kb): 65535

在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A 由26 个小写英文字母组成A={a,b,…,z}。该字母表产生的升序字符串是指字符串中字母按照从左到右出现的次序与字母在字母表中出现的次序相同,且每个字符最多出现1 次。例如,a,b,ab,bc,xyz 等字符串都是升序字符串。现在对字母表A 产生的所有长度不超过6 的升序字符串按照字典序排列并编码如下。

1 2 … 26 27 28 …
a b … z ab ac …

对于给定的长度不超过6 的升序字符串,编程计算出它在上述字典中的编码。

Description

文件的第一行是一个正整数k,表示接下来共有k 行。 
接下来的k行中,每行给出一个字符串。

Input

共有k 行,每行对应于一个字符串的编码。

Output

1

2

3

2

a

b

Sample Input

1

2

1

2

Sample Output

解题思路:这道题用数位dp的话不太现实(状态设计太诡异的说~~~)

     那么指定个  字母   只有一个排列合法,符合组合数的概念,可以考虑使用组合数

     然后在当前状态下,求长度小于len的总个数,等于len的当前序列的总个数(相当于把问题细化了)

     具体的看代码吧~~~

值得注意的是   利用杨辉三角计算组合数   且合数性质cur[i][j]=cur[i][i-j];

代码如下:

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4
 5 char s[7];
 6 int cur[27][27] = { 1 };
 7
 8 //预处理 利用杨辉三角计算组合数
 9 void init(){
10     int i, left, right;
11     for (i = 1; i <= 26; i++){
12         cur[i][0] = cur[i][i] = 1;
13         left = 1, right = i - 1;
14         while (left <= right){
15             cur[i][left] = cur[i - 1][left - 1] + cur[i - 1][left];
16             cur[i][right--] = cur[i][left++];//组合数性质cur[i][j]=cur[i][i-j];
17         }
18     }
19 }
20
21 //长度小于len的串的个数
22 int minlen_num(int len){
23     int i, cnt = 0;
24     for (i = 1; i < len; i++)
25         cnt += cur[26][i];
26     return cnt;
27 }
28
29 //当前长度下当前串前面的个数
30 int enquallen_num(int len){
31     int i, j, cnt = 0, pre = -1, tmp;
32     for (i = 0; i < len; i++){
33         tmp = s[i] - ‘a‘;
34         for (j = pre + 1; j < tmp; j++)
35             cnt += cur[26 - j - 1][len - i - 1];
36         pre = tmp;
37     }
38     return cnt;
39 }
40
41 bool judge(int len){
42     for (int i = 1; i < len; i++)
43     if (s[i] <= s[i - 1])
44         return false;
45     return true;
46 }
47
48 int main(){
49     init();
50     int t, cnt, len;
51     cin >> t;
52     while (t--){
53         cnt = 0;
54         cin >> s;
55         len = strlen(s);
56         if (!judge(len)) cout << 0 << endl;
57         else{
58             cnt += minlen_num(len);
59             cnt += enquallen_num(len);
60             cout << cnt + 1 << endl;
61         }
62     }
63     return 0;
64 }

时间: 2024-10-03 13:28:13

swust oj 715--字典序问题(组合数预处理)的相关文章

[Swust OJ 247]--皇帝的新衣(组合数+Lucas定理)

题目链接:http://acm.swust.edu.cn/problem/0247/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 在很久很久以前,有个臭美国王.一天,他得到了一件新衣,于是决定巡城看看老百姓的反应(囧).于是他命令可怜的宰相数一下他有多少种巡城方案. 城市是一个N*M的矩形,(N+1)*(M+1)条街把城市分成了N*M块.国王从左下角出发,每次只能向右或向上走,右上角是终点. 请你帮帮可怜的宰相. Input

swust oj 1026--Egg pain&#39;s hzf

题目链接:http://acm.swust.edu.cn/problem/1026/ Time limit(ms): 3000 Memory limit(kb): 65535 hzf is crazy about reading math recently,and he is thinking about a boring problem. Now there are n integers Arranged in a line.For each integer,he wants to know

SWUST OJ Euclid&#39;s Game(0099)

Euclid's Game(0099) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 1855 Accepted: 589 Description Starts with two unequal positive numbers (M,N and M>N) on the board. Two players move in turn. On each move, a player has to write on the boar

swust oj 649--NBA Finals(dp,后台略(hen)坑)

题目链接:http://acm.swust.edu.cn/problem/649/ Time limit(ms): 1000 Memory limit(kb): 65535 Consider two teams, Lakers and Celtics, playing a series of NBA Finals until one of the teams wins n games. Assume that the probability of Lakers winning a game is

线段树 [SWUST OJ 764] 校门外的树 Plus Plus

校门外的树 Plus Plus(0764) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 214 Accepted: 15 Description 西南某科技大学的校门外长度为 L 的公路上有一排树,每两棵相邻的树之间的间隔都是 1 米.我们可以把马路看成一个数轴,马路的一端在数轴 1 的位置,另一端在 L 的位置:数轴上的每个整数点,即 1,2,……,L,都种有一棵树. 现在要将这排树的某一段涂成某种颜色,给定 N 组区间[ 

背包 [POJ 2184 SWUST OJ 145] Cow Exhibition

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9479   Accepted: 3653 Description "Fat and docile, big and dumb, they look so stupid, they aren't much  fun..."  - Cows with Guns by Dana Lyons The cows want to prove to

[Swust OJ 404]--最小代价树(动态规划)

题目链接:http://acm.swust.edu.cn/problem/code/745255/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ (2+3))=((5)+(5))=10.除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果相加

swust oj 1126--神奇的矩阵(BFS,预处理,打表)

题目链接:http://acm.swust.edu.cn/problem/1126/ Time limit(ms): 1000 Memory limit(kb): 65535 上一周里,患有XX症的哈特13成功解决了填数矩阵问题.不知道他这一周又从哪儿弄来一神奇的矩阵,于是逃课潜心研究了一周,终于发现了其中的奥秘:该矩阵有2行.4列,即8个小方块,每个小方块上有一个数字,即:1 2 3 45 6 7 8对于这个神奇的矩阵,有3种变换方式,具体如下:变换A:上下两行数字互换,如上图可变为:5 6

swust oj 541--排列字典序问题

题目链接:http://acm.swust.edu.cn/problem/0541/ Time limit(ms): 2000 Memory limit(kb): 65535 n个元素{1,2,..., n }有n!个不同的排列.将这n!个排列按字典序排列,并编号为0,1,…,n!-1.每个排列的编号为其字典序值.例如,当n=3时,6 个不同排列的字典序值如下: 0       1     2    3     4    5 123 132 213 231 312 321 任务:给定n 以及n