输出将字符串中的∗全部放到一起所需要的最小步数。
只有当移动的位置是.才能移动
中位数:将数组大小为n的数据,从大到小,或者是从小到大排列,那么当n为奇数的时候,中位数就是(n+1)/2的这个数,当n为偶数的时候,中位数就是n/2和(n+1)/2这二个数据的平均数。
设有X1, X2,..., Xn N个数, 要找出它们在数轴上距离之和最近的一个点x
那么x一定在X1 和 Xn之间,由于X1 和 Xn之间上的任意一点到X1 和Xn的距离固定,所以我们不考虑X1 和 Xn
那么x一定在X2 和Xn-1之间,
依此类推......可以知道x是这N个数的中位数
void solve(){ int sum=0; cin>>n>>s+1; for(int i=1;i<=n;++i) { if(s[i]=='*') sum++; } sum=(sum+1)/2; int cnt=0,pos=0; for(int i=1;i<=n;++i){ if(s[i]=='*'){ cnt++; } if(cnt==sum){ pos=i;break; } } cnt=0;int ans=0; for(int i=1;i<=n;++i){ if(s[i]=='*'){ cnt++; ans=ans+abs(pos-i)-abs(sum-cnt); } } cout<<ans<<" "; }
dp
移动到i左侧和右侧各自的花费
ll l[maxn],r[maxn],cntl[maxn],cntr[maxn]; ll cal(ll x,ll y) { if(x>y)return 0; return ((x+y)*(y-x+1)/2); } void solve() { cin>>n; cin>>s; l[0]=r[n+1]=0; cntl[0]=cntr[n+1]=0; rep(i,1,n)l[i]=l[i-1]+(s[i-1]=='*')*i,cntl[i]=cntl[i-1]+(s[i-1]=='*'); dec(i,n,1)r[i]=r[i+1]+(s[i-1]=='*')*i,cntr[i]=cntr[i+1]+(s[i-1]=='*'); ll ans=INF; rep(i,1,n) ans=min(ans,cal(i-cntl[i]+1,i)-l[i]+r[i+1]-cal(i+1,i+cntr[i+1])); cout<<ans<<" "; }