传送门 : https://cn.vjudge.net/problem/Gym-101078L
思路:
不难 分析出,所有移动的总步数是一定的,但是因为对每一个分支进行开平方,这样使得总和发生了变化
但是 对于5来说
1+1+1+1+1
1+2+2
1+2+1+1
2+3
5
开平方来说,很明显上述开平方求和,最后一种情况的值最小。
所以,对于整个01字符串来说,最先出现的1 一定要和最后出现的0 交换,这样的话,得到的总和最小
#include <iostream>
#include<cstdio>
#include <cstring>
#include <cmath>1
using namespace std;
char s[55050];
int main ()
{
scanf("%s",s);
int n=strlen(s);
int ans=0;
for(int i=0;i<n;i++)
{
if(s[i]=='1')
{
ans++; //数出1的个数
}
}
int j=n-ans; //从j到 n-1 所有位置应该全部为1
int i=j-1; //从这个点往前找出所有的1
double sum=0;
while(i>=0 && j<n)
{
while(s[i]=='0') //i 找前面的1,为0的话,自-
{
i--;
}
while(s[j]=='1') // j 往后找0, 为1的话 自+
{
j++;
}
if(i>=0 && j<n) // 如果没有这个限制条件的话,当 i<0 或者 j>=n 以后,会多一步多余运算
{
sum+=sqrt(j-i);
i--;
j++;
}
}
printf("%.12lf\n",sum);
}