uva 714 Copying Books 最大值最小化 附測試數據

題目大意:

給出一些書的頁數,讓你求把這些書分成m份,其中最大的一份最小可能有多少頁數。最大值最小化問題。


分析:
屬於最大值最小化問題。要用到二分法找到可能取到的最小值,然後嘗試着把這些書分成若干份。如果有多解,輸出第一份儘可能小的,如果第一份相同,輸入第二份儘可能小的,以此類推。

1、輸入的時候要記錄最大的頁數,在二分的時候如果mid小於最大的頁數,直接l=mid+1,後面不用考慮。

2、知道了最小的可能值,分份數的時候要從後往前分,因爲這樣才能保證最優解。

3、如果分完發現份數小於要求的數量,從前往後添加‘ / ’。保證最優解。


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#define pi acos(-1.0)
#define eps 1e-6
#define ll long long
using namespace std;
int main()
{
    int t,n,k;
    cin>>t;
    int a[550];
    while(t--)
    {
        cin>>n>>k;
        ll sum=0;
        int Max=0;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            sum+=a[i];
            Max=max(Max,a[i]);
        }
        ll l,r,mid;
        l=0,r=sum;
        while(l<=r)
        {
            mid=l+r>>1;
            if(mid<Max)
            {
                l=mid+1;
                continue;
            }
            int tot=1;
            ll temp=0;
            for(int i=0;i<n;i++)
            {
                temp+=a[i];
                if(temp>mid)
                {
                    tot++;
                    temp=a[i];
                }
            }
            if(tot<=k)
                r=mid-1;
            else
                l=mid+1;
        }
      //  cout<<l<<endl;
        ll temp=0;
        int tot=0;
        int ans[550];
        memset(ans,0,sizeof(ans));
        for(int i=n-1;i>=0;i--)
        {
            temp+=a[i];
            if(temp>l)
            {
                tot++;
                temp=a[i];
                ans[i]=1;
            }
        }
        if(tot<k-1)
        {
            for(int i=0;i<n;i++)
            {
                if(!ans[i])
                {
                    ans[i]=1;
                    tot++;
                    if(tot==k-1)
                        break;
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            if(!i)
                printf("%d",a[i]);
            else
                printf(" %d",a[i]);
            if(ans[i])
                printf(" /");
        }
        printf("\n");
    }
    return 0;
}



附上幾組測試數據

10
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
5 1
2 2 2 2 2
6 4
1 1 1 1 1 900
5 3
2 7 3 3 5
7 3
2 2 2 1 1 1 2
5 3
1 1 1 1 10
6 3
1 2 3 3 2 1
9 3
900 800 700 600 500 400 300 200 100
4 2
9000 1 1 1

100 200 300 400 500 / 600 700 / 800 900
100 / 100 / 100 / 100 100
2 2 2 2 2
1 / 1 / 1 1 1 / 900
2 7 / 3 / 3 5
2 2 / 2 1 / 1 1 2
1 / 1 1 1 / 10
1 / 2 3 / 3 2 1
900 800 / 700 600 / 500 400 300 200 100
9000 / 1 1 1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章