題意:把一個非整數數組分成若干個子數組,使得子數組和的最大值最小
題解:剛剛想起來,艾神曾經說過一看到最大值最小就得想到二分。好吧,以後區間求值都要往二分上去想,不過還是有動態規劃的思路的。
方法一:動態規劃(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;
}