009:月度开销
Posted MalcolmMeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了009:月度开销相关的知识,希望对你有一定的参考价值。
描述
农夫约翰是一个精明的会计师。他意识到自己可能没有足够的钱来维持农场的运转了。他计算出并记录下了接下来 N (1 ≤ N ≤ 100,000) 天里每天需要的开销。
约翰打算为连续的M (1 ≤ M ≤ N) 个财政周期创建预算案,他把一个财政周期命名为fajo月。每个fajo月包含一天或连续的多天,每天被恰好包含在一个fajo月里。
约翰的目标是合理安排每个fajo月包含的天数,使得开销最多的fajo月的开销尽可能少。
输入第一行包含两个整数N,M,用单个空格隔开。
接下来N行,每行包含一个1到10000之间的整数,按顺序给出接下来N天里每天的开销。输出一个整数,即最大月度开销的最小值。样例输入
7 5 100 400 300 100 500 101 400
样例输出
500
提示若约翰将前两天作为一个月,第三、四两天作为一个月,最后三天每天作为一个月,则最大月度开销为500。其他任何分配方案都会比这个值更大。
WA:
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<map> #include<cstring> #define DEBUG(x) cout << #x << " = " << x << endl using namespace std; const int MAXN=1e5+10; int N,M; int dayConsume[MAXN]; int feasible(int n) { int ptr=0; int minCnt=0; while(ptr<N){ int sum=0; while(true){ sum+=dayConsume[ptr]; if(sum>n)break; else ptr++; } minCnt++; } return cnt-M; } int BinSearch(int lb,int rb) { int lastPos=1<<30; while(lb<=rb){ int mid=lb+(rb-lb)/2; int t=feasible(mid); if(t>0){ lb=mid+1; } else if(t<0){ rb=mid-1; } else { if(mid<lastPos){ lastPos=mid; rb=mid-1; } else { lb=mid+1; } } } return lastPos; } int main() { freopen("in.txt","r",stdin); scanf("%d %d",&N,&M); int lb=0; int rb=0; for(int i=0;i<N;i++){ int t; scanf("%d",&t); dayConsume[i]=t; rb+=t; lb=lb<t?t:lb; } printf("%d",BinSearch(lb,rb)); return 0; }
AC:
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<map> #include<cstring> #define DEBUG(x) cout << #x << " = " << x << endl using namespace std; const int MAXN=1e5+10; int dayConsume[MAXN]; int N,M; bool isValid(int n) { int m=1;///1?为什么是1 int curCost=0; for(int i=0;i<N;i++){ if(dayConsume[i]>n)return false; if(curCost+dayConsume[i]>n){ m++; curCost=dayConsume[i]; if(m>M)return false; } else { curCost+=dayConsume[i]; } } return true; } int BinSearch(int lb,int rb) { int lastPos=-1; while(lb<=rb){ int mid=lb+(rb-lb)/2; if(isValid(mid)){ lastPos=mid; rb=mid-1; } else { lb=mid+1; } } return lastPos; } int main() { // freopen("in.txt","r",stdin); scanf("%d %d",&N,&M); int lb=1<<30,rb=0; for(int i=0;i<N;i++){ scanf("%d",&dayConsume[i]); int t=dayConsume[i]; rb+=t; lb=min(lb,t);///?为什么不是max } printf("%d ",BinSearch(lb,rb)); return 0; }
WA和AC两份代码,后者更加符合二分的特点。AC代码是用true或false来标定条件是否成立,WA的代码是用返回值的正负是否为零作为判断依据。
以上是关于009:月度开销的主要内容,如果未能解决你的问题,请参考以下文章