您的位置:首页 > 其它

poj1850 code 字串的编号

2014-08-11 17:17 399 查看
题意:合法字串满足字符从左到右严格递增,所有的合法字串按照优先长度递增,其次字典序递增排列,求给定一个字符串,是否合法,若合法,编号为几?

分析:依旧是数位DP的思想,预处理出长度为i,首字母为j的字符串个数 f [ i ] [ j ]。

给定字符串,首先加上长度小于它的字符串的个数。

然后依次枚举第一个小于原字符串的位置,加上该位字母大于前一位、小于后一位的字符串的个数。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;
long long  f[20][30];//长度为i,以j开头的字符串的个数
int num[20],len;
int initi()
{
int i,j,k;
memset(f,0,sizeof(f));
for(i=0;i<26;i++)
f[1][i]=1;
for(i=2;i<=10;i++)
{
for(j=0;j<26;j++)
{
for(k=j+1;k<26;k++)
f[i][j]+=f[i-1][k];
}
}
}
long long cal()
{
long long sum=0,i,j,k;
for(i=1;i<len;i++)
{
for(j=0;j<26;j++)
sum+=f[i][j];
}
for(i=0;i<len;i++)
{
if(i==0)
{
for(j=0;j<num[i];j++)
sum+=f[len][j];
}
else
{
for(j=num[i-1]+1;j<num[i];j++)
sum+=f[len-i][j];
}
}
return sum;
}
int main()
{
char s[20];
int yes=1,i;
initi();
scanf("%s",s);
len=strlen(s);
num[0]=s[0]-'a';
for(i=1;i<len;i++)
{
num[i]=s[i]-'a';
if(num[i]<=num[i-1])
{
yes=0;
printf("0\n");
break;
}
}
if(yes==1)
{
printf("%I64d\n",cal()+1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: