poj 1850 Code

此题刚看到便想会不会有什么规律,找到相邻间的数据间的联系。首先想用什么来表示最基本的状态,我们看题目要求输入的数据是一个字符串,一个字符串我们可以提取出什么数据呢,有字符串的长度和字符串里包含什么字符,字符串的长度可以放入基本状态中,字符串中包含的字符当然不可以完全放入基本状态中,我们要把哪个字符保留下来呢?根据题目的要求如果是尾字母变化太快不适合,首字母比较适合。基本状态包含两个数据我们用一个二维数组来表示。
dp[i][j]表示以第 i 个字母开头,长度为 j 的字符串的个数。此时就看看dp[i][j]和相邻的数据间有什么关系。我们考虑一个具体的例子。 字符串 WZ代表的数值等于以x开头的长度为2的 字符串的个数 加上以 x 开头的长度为1的个数 ,从而得到 dp[i][j] += dp[i+1][j];  dp[i][j] += dp[i+1][j-1
] , 最后计算时要减去相应长度的所有字符串的个数,然后加上给出数据相应字符串的个数,代码注释里有解释。

#include <stdio.h>
#include <string.h>
#define MAX_char 27
#define MAX_length 20

__int64 dp[MAX_char][MAX_length], ans, sum[MAX_length];
char str[MAX_length];

int main()
{
	memset(dp, 0, sizeof(dp));
	memset(sum, 0, sizeof(sum));
	for(int i = 1; i < 27; i++) dp[i][1] = 1;
	for(int j = 2; j <= 10; j++)
	{
		for(int i = 27 - j; i >= 1; i--)
		{
			dp[i][j] += dp[i + 1][j];
			dp[i][j] += dp[i + 1][j - 1];
		}
	}
	for(int i = 1; i <= 10; i++)
	{
		for(int j = 1; j <= 26; j++)
		{
			sum[i] += dp[j][i];
		}
	}
	scanf("%s", str);
	int len = strlen(str);
	for(int i = 1; i <= len; i++)
	{
		ans += sum[i];
	}
	ans -= 	sum[len];
	int j = 1;
	for(int i = len; i >= 1; i--)   // 例如 bf 要加上 以a为开头长度为2的字符串的个数和
	{				//分别以 c e为开头长度为1的字符串的个数
		for(; j < (str[len - i] - 'a') + 1; j++)
		{
			ans += dp[j][i];
		}
		j++;
	}
	for(int i = 0; i < len - 1; i++)
	{
		if(str[i] >= str[i + 1]) ans = -1;
	}
	printf("%I64d\n", ans + 1);
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值