您的位置:首页 > 其它

POJ - 3273 Monthly Expense(二分搜索:最小化最大值)

2014-04-08 22:30 405 查看
http://poj.org/problem?id=3273

无数WA,参照AC代码才发现

最后一天的cnt++的判定错了,要放在if外面

int check(int sub)
{
int sum=0,k=0,i;
for(i=0;i<N;i++)
{
sum+=a[i];
if(sum>sub)
{
k++;
sum=a[i];
}
}
if(sum!=0) k++;
return k<=M;
}


另一种上下界判定的二分搜索:

//在其他的题目中:使用(low+high)/2可能会有整数溢出的问题

//(问题会出现在当low+high的结果大于表达式结果类型所能表示的最大值时,

//这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)不存在这个问题

void solve1(int a, int b)
{
int l = a, r = b;
int res = 0;
while(l <= r)
{
int mid = l + (r-l)/2;
if(C(mid))
{
r = mid - 1;
res = mid;
}
else
l = mid + 1;
}
printf("%d\n", res);
}


#include <iostream>
#include <cstdio>
using namespace std;
const int MAX_N = 1e5, INF = 1e4 * MAX_N+1;
int L, N, M;
int a[MAX_N+10];
bool C(int x)
{
int cnt = 0, sum = 0;
for(int i = 0; i < N; i++)
{
if(sum + a[i] > x) //总和超过预算
{
if(a[i] > x) return false; //变大
sum = a[i];
cnt++;
if(cnt > M)
return false; //变大
}
else
{
sum += a[i];
}
}
if(sum > 0)
cnt++; //有剩余
if(cnt <= M)
return true; //变小
else
return false; //变大
}
void solve1(int a, int b) { int l = a, r = b; int res = 0; while(l <= r) { int mid = l + (r-l)/2; if(C(mid)) { r = mid - 1; res = mid; } else l = mid + 1; } printf("%d\n", res); }
void solve(int a, int b)
{
int l = a-1, r = b;
while(r - l > 1)
{
int mid = (l + r) / 2;
if(C(mid))
r = mid; //符合条件,尝试更小
else
l = mid; //不符合条件,变大
}

printf("%d\n", r);
}

int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d%d", &N, &M);
int Max = -1, sum = 0;
for(int i = 0; i < N; i++)
{
scanf("%d", a+i);
Max = max(Max, a[i]);
sum += a[i];
}
solve(Max, sum);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分搜索