Remove the Bracket

题意:    

解法:

分析我们会发现当xi和yi这两个值处于两个极端(一个尽可能大,一个尽可能小)时,我们的式子的值才能最小化;又因为(xi-s)*(yi-s)>=0,xi*yi>=(xi+yi)*s-s*s;又因为xi+yi=a[i],所以a[i]*xi-xi*xi>=a[i]*s-s*s;这时我们二分找到当前最小的xi的值,之后我们再利用dp,分别用xi,yi跟前面的x[i-1],y[i-1]相结合结果取最小值即可 

注意当我们数组中含有0的时候,我们最小值不一定是0

const int N = 5e5 + 10, M = 5e2 + 10;
int n,m;
int a[N],b[N],c[N],dp[N][10];
void df()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=2;i<=n-1;i++)
		{
			int num=a[i]*m-m*m;
			int l=0,r=min(m,a[i]);
			while(l<r)//找到最小的xi
			{
				int mid=(l+r)/2;
				int tt=a[i]*mid-mid*mid;
				if(tt>=num)r=mid;
				else l=mid+1;
			}
			b[i]=l;
			c[i]=a[i]-l;
		}
		dp[0][1]=dp[0][2]=a[1];
		b[1]=c[1]=a[1];
		for(int i=2;i<=n-1;i++)
		{
			dp[i][1]=min(dp[i-1][2]+b[i-1]*b[i],dp[i-1][1]+c[i-1]*b[i]);
			dp[i][2]=min(dp[i-1][2]+b[i-1]*c[i],dp[i-1][1]+c[i-1]*c[i]);
		}
		int ans=0;
		ans=min(dp[n-1][2]+a[n]*b[n-1],dp[n-1][1]+a[n]*c[n-1]);
		cout<<ans<<endl;
} 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值