偶尔看到中山大学也有个judge online的东东。发现第一题就是个动态规划的题目。
题目如下,
大概的意思就是说A用1表示,B用2表示,以此类推,那么Z就用26表示,给你一串密文25114,那么就有BEAN,BEAAD,YAAD, YAN, YKD, BEKD,6种可能,现在问,给你一串合法的数字串,解密后有几种可能?
Alice and Bob need to send secret messages to each other and are discussing ways to encode their messages: Alice: "Let's just use a very simple code: We'll assign `A' the code word 1, `B' will be 2, and so on down to `Z' being assigned 26." Bob: "That's a stupid code, Alice. Suppose I send you the word `BEAN' encoded as 25114. You could decode that in many different ways!" Alice: "Sure you could, but what words would you get? Other than `BEAN', you'd get `BEAAD', `YAAD', `YAN', `YKD' and `BEKD'. I think you would be able to figure out the correct decoding. And why would you send me the word `BEAN' anyway?" Bob: "OK, maybe that's a bad example, but I bet you that if you got a string of length 500 there would be tons of different decodings and with that many you would find at least two different ones that would make sense." Alice: "How many different decodings?" Bob: "Jillions!" For some reason, Alice is still unconvinced by Bob's argument, so she requires a program that will determine how many decodings there can be for a given string using her code.
Input
Input will consist of multiple input sets. Each set will consist of a single line of digits representing a valid encryption (for example, no line will begin with a 0). There will be no spaces between the digits. An input line of `0' will terminate the input and should not be processed
Output
For each input set, output the number of possible decodings for the input string. All answers will be within the range of a long variable.
Sample Input
25114111111111133333333330
Sample Output
6891这个问题咋一看,好想可以用2叉树递归下去算出来,不过再想一下,好想有点不现实,数据量实在有点大。
想了下,应该是动态规划比较符合这道题。
思路:那25127举例
先看第一个数字2,那么只有一种可能B
再看5,那么就是2和5,可以是2,5或者25即B,E或者Y
再看1,那么就是251,可以是2,5,1或者25,1
再看2,就是2512, 可以是2,5,1,2或者25,1,2或者2,5,12或者25,12
再看7,就是25127,可以是2,5,1,2,7或25,1,2,7或者2,5,12,7或者25,12,7
这里可以看到规则,
用d(i)表示有i个数字时的可能数量, v(i)表示第i个数的值
d(i) =
d(i-2), if v(i) is zero
d(i-1) + d(i-2), if (1<=v(i)<=9 and v(i-1)==1 ) or (1<=v(i)<=6 and v(i-1)==2)
d(i-1), other conditions
#include#include #include using namespace std;int main(){ string strInput; vector viCount; while(true) { strInput.clear(); viCount.clear(); cin >> strInput; if(strInput[0] == '0') { break; } int len = strInput.length(); /*viCount[i+1]存第i个数字的*/ for(int i = 0; i <= len; i++) { viCount.push_back(1); } for(int i = 1;i < len;i++) { if(strInput[i] == '0') { viCount[i+1] = viCount[i - 1]; } else if((strInput[i] >= '1' && strInput[i] <= '9' && strInput[i - 1] == '1') || (strInput[i] >= '1' && strInput[i] <= '6' && strInput[i - 1] == '2')) { viCount[i+1] = viCount[i] + viCount[i - 1]; } else { viCount[i+1] = viCount[i]; } } cout << viCount[len] << endl; } return 0;}