3273

1 /*
2 此题居然可以用二分来做,首先二分出答案。
3
4 然后判断答案是否合理,问题在于给出一个答案的时候,如何判断合理性
5
6 分析:假如X是答案,既然是答案,那么就把它当成最终的答案,这个可以理解吧。现在对于N个花费,从第一天开始算起
7 算连续几天的和直到大于X为止,然后在从这个截止的天开始从新算,如此类推,因为是答案所以可以这么计算,最后看能算出几个月来,如果
8 在要求的月数之内,那么就符合要求。最后找出最大的答案就是了
9
10 好题
11 */
12
13 // include file
14 #include <cstdio>
15 #include <cstdlib>
16 #include <cstring>
17 #include <cmath>
18 #include <cctype>
19 #include <ctime>
20
21 #include <iostream>
22 #include <sstream>
23 #include <fstream>
24 #include <iomanip>
25 #include <bitset>
26 #include <strstream>
27
28 #include <algorithm>
29 #include <string>
30 #include <vector>
31 #include <queue>
32 #include <set>
33 #include <list>
34 #include <functional>
35
36 using namespace std;
37
38 // typedef
39 typedef long long LL;
40 typedef unsigned long long ULL;
41 typedef __int64 Bint;
42
43 //
44 #define read freopen("in.txt","r",stdin)
45 #define write freopen("out.txt","w",stdout)
46 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
47 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
48 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
49 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
50 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
51 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
52 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
53
54 #define FF(i,a) for(int i=0;i<(a);i+++)
55 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
56 #define Z(a) (a<<1)
57 #define Y(a) (a>>1)
58
59 const double eps = 1e-6;
60 const double INFf = 1e10;
61 const int INFi = 1000000000;
62 const double Pi = acos(-1.0);
63
64 template<class T> inline T sqr(T a){return a*a;}
65 template<class T> inline T TMAX(T x,T y)
66 {
67 if(x>y) return x;
68 return y;
69 }
70 template<class T> inline T TMIN(T x,T y)
71 {
72 if(x<y) return x;
73 return y;
74 }
75 template<class T> inline void SWAP(T &x,T &y)
76 {
77 T t = x;
78 x = y;
79 y = t;
80 }
81 template<class T> inline T MMAX(T x,T y,T z)
82 {
83 return TMAX(TMAX(x,y),z);
84 }
85
86
87 // code begin
88 #define MAXN 100010
89 int N,M;
90 int D[MAXN],L,R,mid,ans,Dmax;
91 bool Isok(int res)
92 {
93 int cnt = 0;
94 int sum;
95 for(int i=0;i<N;)
96 {
97 sum = 0;
98 int j=i;
99 do{
100 //if(D[j]>res) return false;
101 sum += D[j++];
102 }while(j<N&&sum<=res);
103 cnt++;
104 if(sum>res) i=--j;
105 else i=j;
106 }
107 if(cnt<=M) return true;
108 return false;
109 }
110 int main()
111 {
112 read;
113 write;
114 while(scanf("%d %d",&N,&M)!=-1)
115 {
116 L = 0;
117 R = 0;
118 Dmax= 0 ;
119 FORi(0,N,1)
120 {
121 scanf("%d",&D[i]);
122 R += D[i];
123 if(D[i]>Dmax) Dmax = D[i];
124 }
125 R++;
126 ans = INFi;
127 while(L<R)
128 {
129 mid = Y(L+R);
130 if(mid>=Dmax&&Isok(mid))
131 {
132 R = mid;
133 if(mid<ans)
134 ans=mid;
135 }
136 else
137 L = mid+1;
138 }
139 printf("%d\n",ans);
140 }
141 return 0;
142 }

posted @ 2011-03-10 09:42  AC2012  阅读(604)  评论(0编辑  收藏  举报