POJ3273-Monthly Expense

题意:

给你n天的预期,你需要把这n天划分成m段(保证原序列位置不变),让你使这m段中的最大值尽可能小,你要怎么划分。

 

题解:

 1 //题解:
 2 //题目很明显就是一道二分题。你要去二分答案。
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 #include<iostream>
 6 #include<string.h>
 7 #include<algorithm>
 8 using namespace std;
 9 const int maxn=500005;
10 const int INF=0x3f3f3f3f;
11 typedef long long ll;
12 int v[maxn],n,m,w[maxn];
13 int panduan(int x)  //我的判断方法就是截取法,首先从0号位置开始看最大能截取到那个位置,然后再从新位置在开始
14 {  //截取
15     int ans=1;
16     for(int i=1;i<=n;++i)
17     {
18         if(v[i]>x) return 0;   
19         if(w[i-1]+v[i]<=x) w[i]=w[i-1]+v[i];
20         else w[i]=v[i],ans++;
21     }
22     if(ans<=m) return 1;  //截取的次数小于m的话就可以。为什么可以自己想一想
23     else return 0;
24 }
25 int main()
26 {
27     while(~scanf("%d%d",&n,&m))
28     {
29         memset(v,0,sizeof(v));
30         memset(w,0,sizeof(w));
31         int r=0;
32         for(int i=1; i<=n; ++i)
33             scanf("%d",&v[i]),r+=v[i];
34         int l=0,mid,ans=r/2; //我一直很疑惑这里的ans要初始化为r/2,不初始化的话就会报错。。。
35         while(l<=r)
36         {
37             mid=(l+r)>>1;
38             if(!panduan(mid))
39             {
40                 l=mid+1;
41             }
42             else
43             {
44                 ans=mid;
45                 r=mid-1;
46             }
47         }
48         printf("%d\n",ans);
49     }
50     return 0;
51 }

 

 

 

posted @ 2019-11-15 08:55  kongbursi  阅读(161)  评论(0编辑  收藏  举报