Description
笨笨在小山顶上种了一棵果树,秋天了,果树结出了许多许多的果子,笨笨要去摘果子。
这是一棵可以结出3种不同果实的树,它的果实长在树枝的分叉处和树顶上。
果实分3种:普通果实、奇异果实和稀有果实。
这颗树的第一个分叉可以用一个2进制码表示(也就是许多的“1”和“0”),
而第一个分叉又分成2个分叉,分别用第一个分叉的前半段和后半段表示(从中间分开),
其他分叉也如此。分叉分到最后只剩下“1”或“0”时就成了树顶。
每个分叉只能分成2个分叉。
表示这棵树第一个分叉的2进制码必定是2的乘方位。
例如:
1 0 1 0
\ / \ /
10 10
\ /
1010
这就是一棵笨笨种的树。
三种果实的分辨方式为:
普通果实:既有“1”又有“0”;
奇异果实:只有“1”;
稀有果实:只有“0”。
每种果实的价值不同,普通果实1元,奇异果实2元,稀有果实5元。
笨笨能摘到的果实范围是一定的,他想知道他所能摘到果实的总价值。
像刚刚所示的“1010”树,它有3个普通果实,2个奇异果实和2个稀有果实,
若笨笨能摘到最高2,最低0,那么他就能得到所有的果实,果实的总价值为3*1+2*2+5*2=17元。
Input
第一行一个数n,表示这个2进制码的位数是2的多少次乘方(即长度为2^n,0<=n<=15)。
第二行2个数u,d,表示笨笨可以摘到的最大高度和最小高度(0<=d<=u<=100000)。
第三行为表示第一个分叉的位数为2^n位的2进制数。
Output
一个数,笨笨所能摘到果子的最大总价值。
Sample Input
3
3 0
10001011
Sample Output
40
同上一题
#include <iostream>
#include <cmath>
#include <string>
#define SIZE 100100
using namespace std;
string s;
int l, up, down, res;
char c[SIZE];
void dfs(int x, int depth)
{
if (x >= l)
{
return;
}
if (depth < down)
{
return;
}
dfs(x + x, depth - 1);
dfs(x + x + 1, depth - 1);
if (depth <= up)
{
switch (c[x])
{
case 'B':
res += 3; // = case 'B': res += 5; break;
case 'I':
++res;
case 'F':
++res;
break;
}
}
return;
}
int main(int argc, char** argv)
{
int n, len, i;
scanf("%d%d%d", &n, &up, &down);
cin >> s;
up = min(up, n);
len = pow(2, n);
l = len << 1;
for (i = len; i < len + len; ++i)
{
if (s[i-len] == '0')
{
c[i] = 'B';
}
else
{
c[i] = 'I';
}
}
len >>= 1;
while (len)
{ // 递推
for (i = len; i < len + len; ++i)
{
if (c[i+i] == c[i+i+1])
{
c[i] = c[i+i];
}
else
{
c[i] = 'F';
}
}
len >>= 1;
}
dfs(1, n);
printf("%d", res);
return 0;
}