题目链接: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支持的协议与封装协议

    <?php /* * php://stdin 标准输入流 * php://stdout 标准输入流 * php://stderr 标准错误流 * php://output 只写的数据流 * ph ...

  2. 算法之旅,直奔<algorithm>之十五 find

    find(vs2010) 引言 这是我学习总结 <algorithm>的第十五篇.关于<algorithm>,每篇都很小,但是都很好用,可以秀出你的个性. 作用 find的作用 ...

  3. 10247 - Complete Tree Labeling(递推高精度)

    Problem B Complete Tree Labeling! Input: standard input Output: standard output Time Limit: 45 secon ...

  4. 用PyRestful快速构建Tornado下REST APIs 的支持

    一.安装PyRestful库 $ pip install pyrestful 二.使用案例 (一)books_service.py # -*- coding: utf-8 -*- import tor ...

  5. 操作 IoT 设备内嵌 SQLite

    Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD   Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本 ...

  6. NET Core个人博客

    NET Core重写个人博客站点小结 今天用ASP.NET Core重写了个人博客站点,原来是基于ASP.NET 4.5开发的.重写工作总体很顺利,最后成功发布到Ubunt+Nginx平台上.效果如下 ...

  7. sed 文件查找,替换

    sed 命令查找与替换: (1)删除第2,3行:sed '2,3d' test.txt > new.txt (2)替换:  替换所有:sed 's/abc/ABC/' test.txt > ...

  8. web.xml中servlet, bean, filter, listenr 加载顺序汇总

    最终得出结果:先 listener >> filter >> servlet >> spring 所以,如果过滤器中要使用到 bean,可以将spring 的加载 ...

  9. Oracle 日期时间

    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from goods t insert into goods (id,createdate) value ...

  10. Android应用--简、美音乐播放器增加音量控制

    Android应用--简.美音乐播放器增加音量控制 2013年6月26日简.美音乐播放器继续完善中.. 题外话:上一篇博客是在6月11号发的,那篇博客似乎有点问题,可能是因为代码结构有点乱的原因,很难 ...