poj 1850(以字符a开始长度为len的个数+数字本身)

Code
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 7265 Accepted: 3398

Description

Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered that the words are made only of small characters of the English alphabet a,b,c, ..., z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).  

The coding system works like this:  
• The words are arranged in the increasing order of their length.  
• The words with the same length are arranged in lexicographical order (the order from the dictionary).  
• We codify these words by their numbering, starting with a, as follows:  
a - 1  
b - 2  
...  
z - 26  
ab - 27  
...  
az - 51  
bc - 52  
...  
vwxyz - 83681  
...  

Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.  

Input

The only line contains a word. There are some constraints:  
• The word is maximum 10 letters length  
• The English alphabet has 26 characters.  

Output

The output will contain the code of the given word, or 0 if the word can not be codified.

Sample Input

bf

Sample Output

55

Source


一道按位dp题目。
关键状态是 dp[i][j] 表示 以i开头长度为j的字符串个数。
初始化为dp[i][1] = 1;
转移方程为 dp[i][j] = dp[i-1][j+1] + dp[i-1][j + 2]  + ... + dp[i-1][25];

再增加一个状态数组sum[i] 表示长度为i的满足条件的字符串有多少个,那么使用上面计算出来的dp可以很快求得。
那么以
vwxyz 为例:
首先result 先加上 sum[1] ~ sum[4]
然后对于长度为5的序列,需要一位一位讨论,这个和poj 3253按位计算的思路是一样的。
首先以小于v开头的长度为5的序列都满足要求。因此加上dp['a'][5] ~ dp['u'][5]
然后固定v,则以小于w大于v的序列也都满足要求。而这样的字母不存在。
然后固定前缀vw, 则以小于x大于w开头的序列也都满足要求。这个数字也是0.
以此类推,固定前缀vwx, vwxy, vwxyz求得的数字也都是0。。

最后再加上 那个数字本身(再加一)

提交记录:
1、WA 因为没有看到题目中的要求, 当字符串不合法时,输出0.
2、Accepted
/*Source Code

Problem: 1850		User: 775700879
Memory: 684K		Time: 16MS
Language: G++		Result: Accepted
Source Code*/
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
          #include 
         
           #include 
          
            #include 
           
             #include 
             #define MAX_V 500 #define oo 0x3f3f3f3f using namespace std; long long dp[30][20] = {0}; long long sum[30] = {0}; int main() { int i, j, k; for (i = 0; i < 26; i++) { dp[i][1] = 1; } for (i = 2; i <= 10; i++) { for (j = 0; j < 26; j++) { for (k = j+1; k < 26; k++) { dp[j][i] += dp[k][i-1]; } } } for (i = 1; i <= 10; i++) { for (j = 0; j < 26; j++) { sum[i] += dp[j][i]; } } char str[20]; int a[20]; int len = 0; scanf("%s", str); i = 0; while (str[i]) a[len++] = str[i++] - 'a'; for (i = 1; i < len; i++) { if (a[i] <= a[i-1]) {cout << 0 << endl; return 0;} } long long result = 0; for (i = 1; i < len; i++) result += sum[i]; for (i = 0; i < len; i++) { int low = (i == 0) ? 0 : a[i-1]+1; for (j = a[i]-1; j >= low; j--) { result += dp[j][len-i]; } } cout << result + 1<< endl; return 0; }  
            
           
          
        
       
       
      
      
     
     
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值