首先,我想犯壹個錯誤。A [100001]的寫法不對。確切的最大值不清楚,但肯定沒有這麽大的下標。這裏的目的只是設置壹個足夠大的數組,沒必要做的那麽大!
好了,言歸正傳:
例如,假設* * *有n個物品,m個人,最不憤怒的人的憤怒度是L,最成年人(即總* * *攜帶物品)的憤怒度是R,第I個物品的權重是a[i],第j個人的憤怒度是b[j](這裏不用)。假設只有兩個結果,平均值設置為mid。
scanf("%d%d ",& ampn & amp;m);?//輸入n個物品,m個人。
for(I = 1;我& lt= n;I++){//輸入n個項目各自的權重,依次賦值,保存總權重和備用。
scanf("%d ",& ampa[I]);
sum+= a[I];
}
r =總和;//默認總數為最大生氣值的默認值(實際可能嗎)
l = 0;//取0為最不生氣的人的生氣值(從這裏開始計算)
int?RS;?//找到控制開關的最大值
while(r-l & gt;1){?//如果最大值和最小值之差小於1,則認為找到了最優解。
mid =(l+r)/2;?//計算中間值(縮小範圍,中間也壹樣,沒必要重復)
sum = 0;?//用來記錄值之間的大概關系。
RS = 1;
for(I = 1;我& lt= n;i++){
if(sum+a[I]& lt;= mid)sum+= a[I];//剛開始的時候,數值不夠大,就讓它們加起來。
else{?//加到壹定程度後,切換到另壹種算法,降低其值,重新計算。
sum = a[I];
if(sum & gt;mid){?//如果這個值遠大於中間值,基本上就是最大值,但不排除會有大於這個的值,所以不使用break語句;?但是給開關壹個大的值。
RS = 10000000;
}
rs++;?//switch加1,證明比平均值多了壹個生氣值。
}
}
如果(rs & gtm)l = mid;//憤怒值大於中值的人數大於總人數,意味著每個人都可以上壹個臺階。
不然呢?如果(rs & lt= m)r = mid;//不然大家都要降壹級,把中值給最大值。
}所以,只要循環結束,以r為值就可以得到最大怒氣的最小值(有點暈,沒關系,多看看就好,看不懂也沒關系,反正也不壹定對,哈哈);