描述
南阳理工学院虽然不算太大, 但是学校里有很多的池塘和树林, 所以学校的风景很不错, 但是校长还是对学校的绿化不满意, 为了给学生带来更好的环境, 学校想对学校在进行一次绿化,这次改造肯定有很多地方需要挖, 那么问题来,应该找谁来完成这个工作呢?
肯定是要找蓝翔的, 现在蓝翔有很多大型工具, 能很快的完成这次的工作, 但是学校很着急啊, 要让他们在尽量短的的时间里完成。但是蓝翔的校长的不知道怎么安排(哎,没学过啊), 他听说我们学校的有很多学算法的, 所以他来找到了你, 想让你给编个程序来解决这个问题,那么问题又来了, 聪明的你能解决它吗?
-
输入
-
第一行,两个数据,第一个是表示有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; }