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

来源:互联网 发布:vue.js是什么 编辑:程序博客网 时间:2024/05/03 23:47

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;}elsel = 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;}elsel = 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;}


0 0
原创粉丝点击