Chain
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 2025 |
|
Accepted: 684 |
Description
Byteland had not always been a democratic country. There were also black pages in its book of history. One lovely day general Bytel − commander of the junta which had power over Byteland −− decided to finish the long−lasting time of war and released imprisoned activists of the opposition. However, he had no intention to let the leader Bytesar free. He decided to chain him to the wall with the bytish chain. It consists of joined rings and the bar fixed to the wall. Although the rings are not joined with the bar, it is hard to take them off.
'General, why have you chained me to the prison walls and did not let rejoice at freedom!' cried Bytesar.
'But Bytesar, you are not chained at all, and I am certain you are able to take off the rings from the bar by yourself.' perfidiously answered general Bytel, and he added 'But deal with that before a clock strikes the cyber hour and do not make a noise at night, otherwise I will be forced to call Civil Cyber Police.'
Help Bytesar! Number the following rings of the chain with integers 1,2,...,n. We may put on and take off these rings according to the following rules:
.only one ring can be put on or taken off from the bar in one move,
.the ring number 1 can be always put on or taken off from the bar,
.if the rings with the numbers 1,...,k−1 (for 1<= k < n) are taken off from the bar and the ring number k is put on, we can put on or take off the ring number k+1.
Write a program which:
.reads from std input the description of the bytish chain,
.computes minimal number of moves necessary to take off all rings of the bytish chain from the bar,
.writes the result to std output.
Input
In the first line of the input there is written one integer n, 1 <= n <= 1000. In the second line there are written n integers o1,o2,...,on (each of them is either 0 or 1) separated by single spaces. If oi=1, then the i−th ring is put on the bar, and if oi=0, then the i−th ring is taken off the bar.
Output
The output should contain exactly one integer equal to the minimal number of moves necessary to take off all the rings of the bytish chain from the bar.
Sample Input
4
1 0 1 0
Sample Output
6
Source
POI 2001
/* http://acm.pku.edu.cn/JudgeOnline/problem?id=1090 这题有点类似于中国的九连环游戏,题意大概是:给定一个长度为n的01字符串data,有求在给点规则下将这个字符串变成全0字符串,求这个过程的最小步骤。规则如下: 1)一步必须且只能改变一位(0可以变成1,1变成0) 2)第一位的字符任意时刻都可以改变 3)给定整数k, 1<=k<n;只有当1-k位的字符全部为0,且第k位字符为1时,第k+1位字符才能改变 这个题是一个明显的递推题 设: f(n)表示将字符串1 - n位全部变为0所需的最小步骤 o(n)表示,将字符串1 - (n - 1)位全部变为0,且第n位为1所需的最小步骤 t(n)表示,当1 - (n - 1)位全为0且第n为为1时,将1-n位全部变为0所需的最小步骤 递推关系如下: f(1) = data[1]; o(1) = 1 - data[1]; t(1) = 1; f(n) = o(n - 1) + 1 + t(n - 1), 当data[n] = 1 f(n - 1), 当data[n] = 0 o(n) = f(n - 1), 当data[n] = 1 o(n - 1) + 1 + t(n - 1); 当 data[n] = 0 t(n) = 2 * t(n - 1) + 1; 由于涉及到指数级运算,__int64也盖不住了,需要用到大数加法。代码里用到了自己写的一个大数加法, 完整的大数加法包可以从我的下载页面下载, 代码如下: */ #include <iostream> #include <string> #define MAX_N 1000 using namespace std; int data[MAX_N + 1]; string takeOff[MAX_N + 1]; int n; string bigIntegerAdd(const string left, const string right) { int lenl = static_cast<int>(left.size()); int lenr = static_cast<int>(right.size()); std::string res = ""; //get the minimum length of the two string int minLen = (lenl <= lenr) ? lenl : lenr; int maxLen = (lenl <= lenr) ? lenr : lenl; std::string longerStr = (lenl <= lenr) ? right : left; int residue = 0, sum = 0, quotient = 0; //add operation, first part int pos1; for(pos1 = 0; pos1 <= minLen - 1; pos1++) { sum = (left[pos1] - '0') + (right[pos1] - '0') + quotient; quotient = sum / 10; residue = sum % 10; res += residue + '0'; } //add operation, second part for(int pos2 = pos1; pos2 <= maxLen - 1; pos2 ++) { sum = (longerStr[pos2] - '0') + quotient; quotient = sum / 10; residue = sum % 10; res += residue + '0'; } //add the extra carry while(quotient != 0) { residue = quotient % 10; quotient = quotient / 10; res += residue + '0'; } //std::cout<<"res size:"<<res.length()<<std::endl; return res; } string f(int n); string o(int n) { if(n == 1) { if(data[n] == 1) return "0"; else return "1"; } if(data[n] == 1) return f(n - 1); else return bigIntegerAdd(bigIntegerAdd(o(n - 1), "1"), takeOff[n - 1]); } string f(int n) { if(n == 1) { if(data[n] == 1) return "1"; else return "0"; } if(data[n] == 0) return f(n - 1); return bigIntegerAdd(bigIntegerAdd(o(n - 1), "1"), takeOff[n - 1]); } int main() { int i; cin>>n; for(i = 1; i <= n; i++) cin>>data[i]; takeOff[1] = "1"; for(i = 2; i <= n; i++) { takeOff[i] = bigIntegerAdd(takeOff[i - 1], takeOff[i - 1]); takeOff[i] = bigIntegerAdd(takeOff[i], "1"); } string res = f(n); for(i = res.length() - 1; i >= 0; i--) cout<<res[i]; cout<<endl; return 0; }