题目:POJ3273、洛谷P2884。
题目大意:有n个数,要分成m份,每份的和要尽可能小,求这个情况下和最大的一份的和。
解题思路:二分答案,对每个答案进行贪心判断,如果最后得出份数>m,则说明答案在[mid+1,r]内,反之在[l,mid]内。我的二分上界是所有数的总和,所以时间复杂度$O(n\log (\sum_{i=1}^{n}a[i]))$。
结果我贪心没考虑全,爆了一发O(≧口≦)O
C++ Code:
#include<cstdio>
using namespace std;
int n,m,a[100005];
long long s;
bool ok(int x){
int p=1;
long long ns=0;
for(int i=1;i<=n;++i){
if(ns+a[i]<=x)ns+=a[i];
else{
++p;
ns=a[i];
if(ns>x)return false;
}
}
return p<=m;
}
int main(){
scanf("%d%d",&n,&m);
s=0;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
s+=a[i];
}
long long l=0,r=s,ans;
while(l<=r){
long long mid=l+r>>1;
if(ok(mid)){
ans=mid;
r=mid-1;
}else l=mid+1;
}
printf("%lld\n",ans);
return 0;
}
本文解析了POJ3273、洛谷P2884题目,采用二分查找与贪心算法结合的方法,对一组数值进行最优划分,以最小化各子集的最大和。通过C++实现,详细介绍了算法流程与时间复杂度分析。
1173

被折叠的 条评论
为什么被折叠?



