最大值最小化问题:
#include<stdio.h>
int main()
{
int n, m;
scanf("%d %d", &n, &m);
int left = 0, right = 0;
int a[1005];
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
if (left < a[i])
{
left = a[i];
}
right += a[i];
}
int mid;
while (left <= right)
{
mid = (left + right) / 2;
int cnt = 1, sum = 0;//一开始先划分成一个组,sum用来记录划分的当前组的和
for (int i = 0; i < n; i++) //对于每一个mid值都要进行n个遍历
{
if (sum + a[i] <= mid)
sum += a[i];
else
{
sum = a[i];
cnt++;
}
}
if (cnt > m)
left = mid + 1;//说明mid取值太小,左端加一
else //包括cnt=m的情况
right = mid - 1;//否则右端减一
}
printf("%d\n", left);//求最大值最小看left
return 0;
}
最小值最大化问题:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
int main()
{
int n, m;
scanf("%d %d", &n,&m);
int i, j;
int a[10005];
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(int), cmp);
int left = 0, right = a[n-1] - a[0];//left理解成两个哨兵站同一个烽火台,right为分别站最左和最右
while (left <= right)
{
int cnt = 1, k = 0;//cnt计算所有符合条件的数字,k一定从0开始(贪心算法)
int mid = (left + right) / 2;//假设的最小值
for (i = 1; i < n; i++)
{
if (a[i] - a[k] >= mid)
{
cnt++;
k = i;
}
}
if (cnt >= m)//cnt>m,说明mid小了,cnt=c,说明至少这个mid的大小符合,但说不定可以更大
left = mid + 1;
else//说明mid大了
right = mid - 1;
}
printf("%d\n", right);//用right不要用left,因为前面if(cnt >= m)的情况下left的增大有风险
return 0;
}