题意:把一个非整数数组分成若干个子数组,使得子数组和的最大值最小
题解:刚刚想起来,艾神曾经说过一看到最大值最小就得想到二分。好吧,以后区间求值都要往二分上去想,不过还是有动态规划的思路的。
方法一:动态规划(n^2超时)
a[s][i](表示以nums[s]结尾并且前面分成i个数组)=min(a[s][i],max(a[k][i-1],sum[s]-sum[k])),其中(i-1<=k<s)
方法二:二分答案
初始值是最小是数组元素中的最大值,最大值是和,不断的取中间,看看以中间那个值满不满足题意。如果满足right=mid,否则,left=mid+1。
代码:
bool check(vector<int>&nums,int sum,int m)
{
int equal=0,i=0,j=0,size=nums.size(),tsum=0;
while(i<size)
{
tsum=tsum+nums[i];
if(tsum<sum) i++;
else if(tsum==sum)
{
tsum=0;
equal=1;
j++;
i++;
}
else
{
tsum=0;
j++;
}
}
if(tsum!=0) j++;
if(j>m) return false;
else return true;
}
int splitArray(vector<int>& nums, int m)
{
unsigned int i,j,k,size=nums.size(),left=0,right=0,mid,num=0;
bool tag1,tag2;
for(i=0; i<size; i++)
{
if(nums[i]>left) left=nums[i];
right+=nums[i];
}
while(left<right)
{
mid=left+(right-left)/2;
if(check(nums,mid,m)==true) right=mid;
else left=mid+1;
}
return left;
}