1 /*
2
3 题意 : M个人 看守 N个 仓库,每个人有个能力值p[i],仓库的安全值 = 能力值/看守的仓库数 ,
4 聘请某人的花费就是他的能力值,求最高的安全值和最小花费。
5
6 两次DP,一次求最高安全值,在根据安全值求最小花费。
7 dp[j]表示 i 个人看守j个仓库的最高安全值
8 */
9
10 #include<cstdio>
11 #include<cstring>
12 #include<algorithm>
13 using namespace std;
14 const int INF=0x3f3f3f3;
15 int dp[1010],p[50];
16 int main()
17 {
18 int n,m,ans=0;
19 while(scanf("%d%d",&n,&m)!=EOF)
20 {
21 if(!n && !m) return 0;
22 for(int i=0;i<m;i++)
23 scanf("%d",&p[i]);
24 memset(dp,0,sizeof(dp));
25 dp[0]=INF;
26 for(int i=0;i<m;i++)
27 for(int j=n;j>=0;j--)
28 for(int k=1;k<=j && k<=p[i];k++)
29 dp[j]=max(dp[j],min(dp[j-k],p[i]/k));
30 ans=dp[n];
31 if(ans>0)
32 {
33 for(int i=1;i<=n;i++) dp[i]=INF;
34 dp[0] = 0;
35 for(int i=0;i<m;i++)
36 for(int j=n;j>=0;j--)
37 for(int k=min(j,p[i]/ans);k>0;k--)
38 dp[j]=min(dp[j],dp[j-k]+p[i]);
39 printf("%d %d\n",ans,dp[n]) ;
40 }
41 else printf("0 0\n");
42 }
43 return 0;
44 }