求解uva 10163 一道DP题ACM高手来
10163守仓库的人背景:
蓝迪公司有N(1 < = N < = 100)个仓库。公司希望有人来看守它们。现在有M(1 < =M< = 30)人应聘这项工作,公司将雇佣一些人。蓝迪的公司以这些规则雇佣人:
1、每个看守人有一个数值Pi(1<=Pi<=1000),代表他们的能力值。
2、所有的仓库是一样的。
3、一个仓库只能被一个人看守,但一个人能看守几个仓库。如果一个看守的能力值是Pi,然后他看管K个仓库。他看管的每个仓库的安全值Uj=Pi div K。(Note:Uj、Pi、K是整型),没人照顾的仓库安全值是0。
4、如果所有的仓库给了人去看管,公司将达到一个安全线L=min(Uj)。(PS:这句话我翻译得很纠结,读者可以参照原句:4.If all the storages is at least given to a man, company will get a safe line L=min Uj)
5、每个月蓝迪公司会依据他们的能力值付给每个看守人工资,这意味着如果一个看守人的能力是Pi,则他的工资将是Pi美元/月。公司将支付所有的工资Y美元。
现在蓝迪公司给你一个报表包括所有的信息包括N、M、P,你的任务是给公司一个最佳选择,令公司在安全线L最高的前提下,付给看守人最少的工资。
输入:
输入文件包含多组数据
每组数据由两行组成:
第一行包含两个数字N和M
第二行有M个数字,表示每个守仓库的人的能力值。
相邻的两个数字间有一个空格。
当N=0,M=0时输入结束。
输出:
每个数据应输出最高的L和最小的Y,它们中间应有一个空格分隔。
样例输入:
2 1
7
1 2
10 9
2 5
10 8 6 4 1
5 4
1 1 1 1
0 0
样例输出:
3 7
10 10
8 18
0 0
我的程序错了!!!
程序代码:
#include<cstdio>
#include<cstring>
#define min(a,b)((a)<(b)?(a):(b))
const int INF=2000000000;
const int maxm=30+1;
const int maxn=100+1;
int n,m;
int a[maxm];
int f[maxm][maxn];
int g[maxm][maxn];
void init()
{
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
for (int i=1;i<=m;i++) scanf("%d",&a[i]);
}
void doit()
{
for (int i=0;i<=m;i++) f[i][0]=INF;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
f[i][j]=f[i-1][j];
for (int k=1;k<=j;k++)
{
int p=min(f[i-1][k-1],a[i]/(j-k+1));
if (p>f[i][j]) f[i][j]=p;
}
}
}
void ouit()
{
if (f[m][n]==0) g[m][n]=0;
else
{
memset(g,127,sizeof(g));
g[0][0]=0;
for (int i=1;i<=m;i++)
{
int v=a[i];
int w=a[i]/f[m][n];
for (int j=w;j>=n;j--)
g[i][j]=min(g[i-1][j],g[i-1][j-w]+v );
}
}
printf("%d %d\n",f[m][n],g[m][n]);
}
int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while (scanf("%d%d",&n,&m),n,m)
{
init();
doit();
ouit();
}
return 0;
}




