题目链接: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];
 
代码如下:
 #include <iostream>
#include <cstring>
using namespace std; char s[];
int cur[][] = { }; //预处理 利用杨辉三角计算组合数
void init(){
int i, left, right;
for (i = ; i <= ; i++){
cur[i][] = cur[i][i] = ;
left = , right = i - ;
while (left <= right){
cur[i][left] = cur[i - ][left - ] + cur[i - ][left];
cur[i][right--] = cur[i][left++];//组合数性质cur[i][j]=cur[i][i-j];
}
}
} //长度小于len的串的个数
int minlen_num(int len){
int i, cnt = ;
for (i = ; i < len; i++)
cnt += cur[][i];
return cnt;
} //当前长度下当前串前面的个数
int enquallen_num(int len){
int i, j, cnt = , pre = -, tmp;
for (i = ; i < len; i++){
tmp = s[i] - 'a';
for (j = pre + ; j < tmp; j++)
cnt += cur[ - j - ][len - i - ];
pre = tmp;
}
return cnt;
} bool judge(int len){
for (int i = ; i < len; i++)
if (s[i] <= s[i - ])
return false;
return true;
} int main(){
init();
int t, cnt, len;
cin >> t;
while (t--){
cnt = ;
cin >> s;
len = strlen(s);
if (!judge(len)) cout << << endl;
else{
cnt += minlen_num(len);
cnt += enquallen_num(len);
cout << cnt + << endl;
}
}
return ;
}

6/18号我又回来了,这道题是可以数位dp的,当时我设计状态的时候果断逗比了~~~直接在递归时,加个判断就限制了后面数字的选取状态就可以强势ac了

(感谢学长的指点)

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
#define N 110 char s[N];
ll bit[N];
ll dp[N][N]; ll dfs(ll pos, ll mx, bool limit, bool fzero)
{
if (pos == -) return ;
if (!limit && !fzero && ~dp[pos][mx]) return dp[pos][mx];
ll end = limit ? bit[pos] : ;
ll ans = ;
for (ll i = fzero ? : mx; i <= end; i++)//这里就判断了后面的字母的选取是否有限制(题目上的升序)
{
ans += dfs(pos - , i + , limit && i == end, fzero && !i);
}
if (!limit && !fzero) dp[pos][mx] = ans;
return ans;
}
ll cal()
{
ll len = strlen(s + );
for (ll i = ; i <= len; i++)
{
bit[len - i] = s[i] - 'a' + ;
}
return dfs(len - , , , );
}
int main()
{
int t;
cin >> t;
while (t--)
{
memset(dp, -, sizeof(dp));
scanf("%s", s + );
int flag = ;
int len = strlen(s + );
for (int i = ; i<len; i++)
{
if (!(s[i]<s[i + ]))
{
flag = ;
break;
}
}
if (!flag) printf("0\n");
else
printf("%lld\n", cal() - );
}
return ;
}

[Swust OJ 715]--字典序问题(组合数预处理/数位dp)的更多相关文章

  1. [UOJ86]mx的组合数——NTT+数位DP+原根与指标+卢卡斯定理

    题目链接: [UOJ86]mx的组合数 题目大意:给出四个数$p,n,l,r$,对于$\forall 0\le a\le p-1$,求$l\le x\le r,C_{x}^{n}\%p=a$的$x$的 ...

  2. Light OJ 1032 - Fast Bit Calculations(数位DP)

    题目大意: 一个数字把他看成二进制数字,数字里又会一些相邻的1,问从0到n至间所有相邻1的总和是多少?   分解成2进制数字,然后数位DP就行了.   ======================== ...

  3. UOJ#275. 【清华集训2016】组合数问题 数位dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ275.html 题解 用卢卡斯定理转化成一个 k 进制意义下的数位 dp 即可. 算答案的时候补集转化一下 ...

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

    题目链接:http://acm.swust.edu.cn/problem/0247/ Time limit(ms): 1000 Memory limit(kb): 65535   Descriptio ...

  5. [Swust OJ 581]--彩色的石子(状压dp)

    题目链接:http://acm.swust.edu.cn/problem/0581/ Time limit(ms): 1000 Memory limit(kb): 65535   Descriptio ...

  6. swust oj 2516 教练我想学算术 dp+组合计数

    #include<stdio.h> #include<string.h> #include<iostream> #include<string> #in ...

  7. BZOJ 3209 花神的数论题 数位DP+数论

    题目大意:令Sum(i)为i在二进制下1的个数 求∏(1<=i<=n)Sum(i) 一道非常easy的数位DP 首先我们打表打出组合数 然后利用数位DP统计出二进制下1的个数为x的数的数量 ...

  8. [Swust OJ 541]--排列字典序问题

    题目链接:http://acm.swust.edu.cn/problem/0541/ Time limit(ms): 2000 Memory limit(kb): 65535 n个元素{1,2,... ...

  9. [Swust OJ 1097]--2014(数位dp)

    题目链接:http://acm.swust.edu.cn/problem/1097/ Time limit(ms): 1000 Memory limit(kb): 32768   今年是2014年,所 ...

随机推荐

  1. php 图片等比缩放

    /** * @method 图片等比缩放 * @param string $srcImage 源图片路径 * @param string $toFile 目标图片路径 * @param integer ...

  2. SubLime2 乱码解决

    参考 http://www.fuzhaopeng.com/2012/sublime-text-2-with-gb2312-gbk-support/ 使用其中提到的方法二安装 首先下载http://su ...

  3. .NET Core 安装

    Visual Studio 2015 和 .NET Core 安装 安装 Visual Studio 和 .NET Core 1.安装 Visual Studio Community 2015,选择 ...

  4. html常用标签有哪些?

    html看似复杂,其实常用的标签并不多,这里总共介绍一些html的常用标签 文字处理: ①标题:<h1> to <h6> ②段落:<p>文字段落</p> ...

  5. Java Date 和 Calendar

    Java 语言的Date(日期),Calendar(日历),DateFormat(日期格式)组成了Java标准的一个基本但是非常重要的部分.日期是商业逻辑计算一个关键的部分,所有的开发者都应该能够计算 ...

  6. JAVA 创建TXT文件,写入文件内容,读取文件内容

    [java]  view plain copy   package com.abin.facade.ws.mail.function; import java.io.BufferedReader; i ...

  7. http协议与http代理

    TCP/IP协议族 TCP/IP(Transmission Control Protocol/InternetProtocol.传输控制协议/网际协议)是用于计算机通信的一个协议族. TCP/IP协议 ...

  8. poj1236 Network of Schools【强连通分量(tarjan)缩点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html  ---by 墨染之樱花 [题目链接]http://poj.org/pr ...

  9. Ext JS学习第九天 Ext基础之 扩展原生的javascript对象

    此文来记录学习笔记: •Ext对于原生的javascript对象进行了一系列的扩展,我们把他们掌握好,更能深刻的体会Ext的架构,从而对我们的web开发更好的服务, 源码位置,我们可以从开发包的这个位 ...

  10. asp.net连接ORACLE数据库

    这段时间维护客户的一个系统,该系统使用的是ORACLE数据库,之前开发的时候用的都是MSSQL,并没有使用过ORACLE.这两种数据库虽然都是关系型数据库,但是具体的操作大有不同,这里作下记录. 连接 ...