sicily 1001 Alphacode

这题一开始没想到dp(动态规划),所以弄了好久好久。后来看别人的blog,知道是dp,就根据推导公式写,结果还是写错,后来发现原来是
自己少处理当前某个位置的数为0的情况。
思路:每次新加入一个数字处理时
(1)不为0
直接拼接的话,那么个数值时可能没变的,如21,原本是3,再加1,可能个数还是1,因为31大于26.
此时再考虑另一种情况,那就是跟前一位结合,如果结合后小于27,那么就是cnt = f1 + f2,因为不拼接是等于f2,现在多一个拼接成功,那么需要
增加f1的可能性的值
(2)为0
这个比较好说,直接等于前2个位置的值,因为0拼接没啥意义,如果可以跟前一位结合成功的话,还是算一个值,不会有11;1,1;这种情况
它就是10。所以就知道是等于前两个位置的。再之前的以此类推。

cnt:个数值,f1,f2:前两位和前一位位置的个数值,
总的分2种大情况
1 当前输入为0的话,个数值不变,cnt = f1
2 不为0的情况
a) 当前输入值与前一位值构成小于27的数大于10的数,大于10是必须的,因为前一位的值可能为0!则cnt=f1+f2
b)否则cnt = f2
然后更新f1和f2的值
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;

int main()
{
	//	freopen("input.txt","r",stdin);
	string s;

	while (cin >> s && s != "0") {
		long long f1, f2, cnt;
		long long i, tmp, n;
		n = s.size();		
		f1 = 1;
		f2 = 1;		

		if (n >= 2 && s[1] != '0'&& (s[0] - '0')*10 + s[1]-'0' < 27)			
				f2++;		
		cnt = f2;
		for (i = 2; i < n; ++i) {			
			if (s[i] != '0') {
				tmp = (s[i-1] - '0')*10 + s[i]-'0';	
				if (tmp <= 26 && tmp > 10)
					cnt = f1 + f2;							
				else
					cnt = f2;						
			}
			else 
				cnt = f1;
			f1 = f2;
			f2 = cnt;
		}
		printf("%d\n",cnt);
	}
	return 0;
}

你可能感兴趣的:(1001,sicily)