NYOJ 1118【蓝翔校长的难题】

描述

南阳理工学院虽然不算太大, 但是学校里有很多的池塘和树林, 所以学校的风景很不错, 但是校长还是对学校的绿化不满意, 为了给学生带来更好的环境, 学校想对学校在进行一次绿化,这次改造肯定有很多地方需要挖, 那么问题来,应该找谁来完成这个工作呢?

  肯定是要找蓝翔的, 现在蓝翔有很多大型工具, 能很快的完成这次的工作, 但是学校很着急啊, 要让他们在尽量短的的时间里完成。但是蓝翔的校长的不知道怎么安排(哎,没学过啊), 他听说我们学校的有很多学算法的, 所以他来找到了你, 想让你给编个程序来解决这个问题,那么问题又来了, 聪明的你能解决它吗?


输入
第一行,两个数据,第一个是表示有N个任务, 第二个是能完成任务的工具有M个(0<N,M<=1000000)。
下面的N行表示完成每个任务的时间t,且不超int(每个任务只能被一个工具完成,且不能被分;工具可以重复使用)。

以EOF结束
输出
每组数据输出一行
样例输入
7 3
2
14
4
16
6
5
3
样例输出
17
提示
样例;
第一个工具工作的时间:16
第二个工具工作的时间:14+3=17

第三个工具工作的时间:6+5+4+2=17




水题,就是考虑的可能多一些。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int num[1000005];
int vis[1000005];
int wa[1000005];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n,m,i,j,sum;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        sum=0;
        memset(vis,0,sizeof(vis));
        memset(wa,0,sizeof(wa));
        for(i=0; i<n; i++)
        {
            scanf("%d",&num[i]);
            sum+=num[i];
        }
        sort(num,num+n,cmp);//从大到小排序
        if(sum%m!=0)       //先求出最小可能
            sum=sum/m+1;
        else sum=sum/m;

        if(sum<num[0])  //如果最大的大于最小可能,直接输出最大的那个任务
        {
            printf("%d\n",num[0]);
            continue;
        }


        for(j=0; j<m; j++)         //类似于背包,往里面填
        {
            for(i=0; i<n; i++)
            {
                if(num[i]<=sum-wa[j]&&vis[i]==0)
                {
                    vis[i]=1;
                    wa[j]+=num[i];
                }
            }
        }
        
        sort(wa,wa+m);    //对于背包排下序

        for(i=0; i<n; i++)
        {
            if(vis[i]==0)//表示有剩余,把剩余的塞进当前背包里最小的
            {
                wa[0]+=num[i];
                sort(wa,wa+m);
                vis[i]=1;
            }
        }
        printf("%d\n",wa[m-1]);//输出最后背包里容量最大的

    }

    return 0;
}


你可能感兴趣的:(NYOJ 1118【蓝翔校长的难题】)