swust oj 648--简单字典(数位dp)

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

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

有这样一本字典,它每个单词一页,单词没有相同字母。 
就像这样: 
a 1 
b 2 


z 26 
ab 27 


az 51 
ba 52 
bc 53 

.

Description

多组测试数据,每行是一个串长最大为10由小写字母组成的单词。 
以EOF结束。

Input

输出这个单词在这本字典的第几页

Output

1

2

3

4

a

az

abc

aa

Sample Input

1

2

3

4

1

51

677

ERROR

Sample Output

解题思路:这道题我们把它看做一个26进制的数位dp就可以了,就查找当前数前面有多少个数就是了,

     值得注意的是这里可以有多个前导零0001,0003等(if (!fzero&&istrue&(1 << i)) continue;),

     当一但出现非零数字后,后面的数字就不能再出现零(istrue | (1 << i))

     关于数位dp不会的可以戳戳这里:http://www.cnblogs.com/zYx-ac/p/4563830.html

代码如下:

 1 /*******************数位dp*************************/
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5
 6 int n, bit[11], judge[27], flag;
 7 char s[11];
 8
 9 int dfs(int pos, int istrue, bool limit, bool fzero){
10     if (pos < 0) return 1;
11     int last = limit ? bit[pos] : 26;
12     int ret = 0;
13     for (int i = fzero ? 0 : 1; i <= last; i++){
14         //允许多个前导零
15         if (!fzero&&istrue&(1 << i)) continue;
16         ret += dfs(pos - 1, istrue | (1 << i), limit&&i == last, fzero&&!i);
17     }
18     return ret;
19 }
20
21 int main(){
22     while (cin >> s){
23         n = strlen(s);
24         flag = 0;
25         memset(judge, 0, sizeof(judge));
26         for (int i = n; i >= 1; i--){
27             bit[n - i] = s[i - 1] - ‘a‘ + 1;
28             if (!judge[bit[n - i]]) judge[bit[n - i]] = 1;
29             else {
30                 flag = 1;
31                 break;
32             }
33         }
34         if (flag) cout << "ERROR\n";
35         else cout << dfs(n - 1, 0, 1, 1) - 1 << endl;
36     }
37     return 0;
38 }

时间: 2024-10-07 15:19:01

swust oj 648--简单字典(数位dp)的相关文章

[Swust OJ 402]--皇宫看守(树形dp)

题目链接:http://acm.swust.edu.cn/problem/402/ Time limit(ms): 5000 Memory limit(kb): 65535 Description 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫.  皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同.  可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫

[Swust OJ 360]--加分二叉树(区间dp)

题目链接:http://acm.swust.edu.cn/problem/360/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下: subtree的左子树的加分×

【上海交大oj】数学题3(数位dp)

1398. 数学题3 题目描述 给定一个数字,他在十进制下从高位到低位一次是n0, n1, n2, n3,... 那么定义它的“差和”为n0-n1+n2-n3+... 如:十进制数字abcdefg,每个字母代表一个位,那么差和为a-b+c-d+e-f+g. 所以十进制数字1234567差和为1-2+3-4+5-6+7=4 现在给你们一个闭区间[m, n],请求出区间内差和为x的数字个数. 输入格式 输入只有一行,三个数字,m n x 30%: 0<= m <= n <=10^3, 50%

简单的数位dp

hdu 2089 设dp[len][flag],flag = 1表示前一位是6,否则前一位不是6. #include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string

SWUST OJ 0032 简单的背包 解题报告

Description 输入数据有多行,包括放入的物品重量为s,物品的件数n,以及每件物品的重量(输入数据均为正整数) 多组测试数据. Input 对于每个测试实例,若满足条件则输出“YES”,若不满足则输出“NO“ Output 20 5 1 3 5 7 9 Sample Input YES 解体思路:贪心不行,,直接上搜索... 1 #include<stdio.h> 2 int w[100],s,n,x,book[100]; 3 void dfs(int weight) 4 { 5 in

swust oj 1097--2014(数位dp)

题目链接:http://acm.swust.edu.cn/problem/1097/ Time limit(ms): 1000 Memory limit(kb): 32768 今年是2014年,所以小明喜欢2014的每一位数字(即:2,0,1,4),小明想知道在区间[l,r](包括l和r)中有多少个数中含有这4个数字(数字无前缀零). Description 多组数据. 每组数据输入2个数l,r(0<l<r<=10^9) Input 输出占一行,即区间[l,r](包括l和r)中包含的满足

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

bzoj 3209: 花神的数论题 数位dp

3209: 花神的数论题 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了.花神的题目是这样的设 sum(i) 表示 i 的二进制表示中 1 的个数.给出一个正整数 N ,花神要问你派(Sum(i)),也就是 sum(

HDU 4734 F(x)(数位DP)

Description For a decimal number x with n digits (A nA n-1A n-2 ... A 2A 1), we define its weight as F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... + A 2 * 2 + A1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there betwe