描述
题解
一个规律题。默认, 取 ,考虑取 ,首先,如果有非最高位 存在 个,有第二个部分公式得答案加上 ,然后根据第三个公式得答案加 并且获取一个新的二进制串 (全是 ),以此类推,直到 。
对于 我们需要考虑两种情况,因为上述循环的第一次取的 不一定全是 。如果 二进制存在至少两个一,例如 ,那么从高位开始查找到第二个 ,假如说第一个 的权值是 ,第二个 的权值是 ,然后取 为 ,此时二进制是 ,也就是说初始存在 个非最高位 ,这是第一种情况;我们还需要考虑一下 取 的情况,计数有多少个非最高位 ,然后在这两种情况中取最优。这样我们就处理完第一轮的运算了,后续的类推,都保证是全 二进制,所以我们可以通过预处理来确定不同长度的全 二进制通过多少次运算可以得到 的状态。
这个题仔细模拟一下,很容易找到规律的,一开始以为是数论题,着实有些虚。
代码
#include <iostream>
#include <string>
using namespace std;
const int MAXN = 2e4 + 10;
string num;
long long temp[MAXN] = {0, 1, 1};
void init()
{
for (int i = 3; i < MAXN; i++)
{
temp[i] = temp[i - 1] + i - 1;
}
}
int main(int argc, const char * argv[])
{
init();
cin >> num;
long long ans = 0;
for (int i = 1; i < num.length(); i++)
{
if (num[i] == '1')
{
ans = (num.length() - 1) - i;
break;
}
}
long long cnt = 0;
for (int i = 1; i < num.length(); i++)
{
if (num[i] == '1')
{
cnt++;
}
}
ans = max(ans, cnt);
ans += temp[num.length()];
cout << ans << '\n';
return 0;
}