複製書稿

Problem Description
現在要把m本有順序的書分給k個人複製(抄寫),每一個人的抄寫速度都一樣,一本書不允許給兩個(或以上)的人抄寫,分給每一個人的書,必須是連續的,比如不能把第一、第三和第四本書給同一個人抄寫。
現在請你設計一種方案,使得複製時間最短。複製時間爲抄寫頁數最多的人用去的時間。
Input
輸入有多組數據,每組數據第1行兩個整數m,k(k<=m<=500);
第2行m個整數,第i個整數表示第i本書的頁數。
Output
對於每組數據輸出k行,每行兩個整數,第i行表示第i個人抄寫的書的起始編號和終止編號。k行的起始編號應該從小到大排列,如果有多解,則儘可能讓前面的人少抄寫。
Sample Input
9 3
1 2 3 4 5 6 7 8 9
Sample Output
1 5
6 7
8 9
//題解:由題意可知,求一個最優的平均值,使K段方差最小,最優解在1與輸入M本書的頁數之和之間,即用二分查找最優解。
//標程:(二分)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[505], b[505], c[505];
int main()
{
//    freopen("a.txt","r",stdin);
    int n, k, i, j;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(n == 0 && k == 0)
        {
            cout << endl;
            continue;
        }
        int sum = 0;
        for(i = 1; i <= n; ++ i)
        {
            cin >> a[i];
            sum += a[i];
        }
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        int l = 1, r = sum, mid;
        while(l <= r)
        {
            mid = (l + r) / 2;
            j = n;
            for(i = 1; i <= k; ++ i)
            {
                int tmp = 0;
                for(; j >= 1; j --)
                    if(tmp + a[j] <= mid)
                       tmp += a[j];
                    else break;
                    b[i] = j;
                if(j == 0) break;

            }
            if(j == 0 && i <= k)
            {
                r = mid - 1;
                for(i = 1; i <= k; ++ i)
                c[i] = b[i];
            }
            else l = mid + 1;
        }
        c[0] = n;
        for(i = k; i > 0; -- i)
            cout << c[i] + 1 << ' ' << c[i-1] << endl;
    }
    return 0;
}
//關鍵字:DP
#include<cstdio>
#include<cstring>
int a[501],d[501];
int f[501][501];
int k,m;
int max(int a,int b) {return a>b?a:b;}
int min(int a,int b) {return a<b?a:b;}
void dg(int i,int j)
{
	if (j==0) return;
	if (j==1)
	{
		printf("1 %d\n",i);
		return;
	}
	int t=i,x=a[i];
	while (x+a[t-1]<=f[k][m])
	{
		x+=a[--t];
	}
	dg(t-1,j-1);
	printf("%d %d\n",t,i);
}
int main()
{
    // freopen("a.txt","r",stdin);
	while(scanf("%d%d",&m,&k)!=EOF)
	{
        if(m==0&&k==0) {printf("\n"); continue;}
		memset(f,0x3f,sizeof(f));
		int i,j,l;
		for (j=1;j<=m;j++)
		{
			scanf("%d",&a[j]);
			d[j]=d[j-1]+a[j];
			f[1][j]=d[j];
		}
		for (i=2;i<=k;i++)  //第i個人
			for (j=1;j<=m;j++) //到第j本書結束
				for (l=1;l<j;l++)//從第l+1本書開始
					f[i][j]=min(f[i][j],max(f[i-1][l],d[j]-d[l]));
		dg(m,k);
	}
	return 0;
}

發佈了268 篇原創文章 · 獲贊 12 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章