码迷,mamicode.com
首页 > 其他好文 > 详细

POJ_3273_Monthly_Expense

时间:2016-04-23 09:03:00      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

描述


http://poj.org/problem?id=3273

分析


二分.

最小化最大值.

和"河中跳房子","Agressive Cows"等最大化最小值问题正好相反的最小化最大值问题,同样用二分解决,原理基本相同,差别主要在C条件的判断上.

1.最大化最小值:

相当于n个东西分给m个人,使得每个人至少拿x个,那么每个人拿够了就走,给后面的人多留一点,只要能分够>=m个人就是true,多的全扔给最后一个人就是了.

2.最小化最大值:

相当于n个东西分给m个人,每个人至多能拿x个,那么每个人尽可能多拿一点,给后面的人少留一点,只要能使<=m个人分完这n个东西就是true,之后每个人随便拿一点给没有拿到的人就是了.

 

注意:

1.如上所述两种问题的区别.

2.关于初始值.有些题直接给前缀和(如之前提到的两题),那样最小值的最大值就是平均值,最大值的最小值也是平均值,但像这道题,如果算sum可能会炸,而且不知道会炸到啥程度,所以不能瞎搞,只能乖乖设定y为0x7fffffff,x为单点最大值.

对于可以计算sum的题有:

<1>.最大化最小值:

x为单点最小值,y为平均值.

<2>.最小化最大值:

x为平均值与单点最大值两者中大的那一个,y为sum.其实直接令x=0,y=0x7fffffff即可,不过循环32次而已...

 

PS.看懂别人的代码不重要,重要的是要理解算法的思想,不同的代码只是实现算法的方式不同与个人喜好问题而已,要真正想明白,把东西转化成自己的.

技术分享
 1 #include<cstdio>
 2 #include<algorithm>
 3 using std :: max;
 4 
 5 const int maxn=100005;
 6 int n,m,maxa=0;
 7 int a[maxn];
 8 
 9 void init()
10 {
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=n;i++)
13     {
14         scanf("%d",&a[i]);
15         maxa=max(maxa,a[i]);
16     }
17 }
18 
19 bool C(int x)
20 {
21     int sum=0,ans=1;
22     for(int i=1;i<=n;i++)
23     {
24         sum+=a[i];
25         if(sum>x)
26         {
27             sum=a[i];
28             ans++;
29         }
30     }
31     if(ans<=m) return true;
32     return false;
33 }
34 
35 void solve()
36 {
37     int x=maxa,y=0x7fffffff;
38     while(x<y)
39     {
40         int m=x+(y-x)/2;
41         if(C(m)) y=m;
42         else x=m+1;
43     }
44     printf("%d\n",x);
45 }
46 
47 int main()
48 {
49     freopen("monthly.in","r",stdin);
50     freopen("monthly.out","w",stdout);
51     init();
52     solve();
53     fclose(stdin);
54     fclose(stdout);
55     return 0;
56 }
View Code

 

 

POJ_3273_Monthly_Expense

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5423817.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!