题意:Pedro有2种巧克力分别有m块和 l块,现在他有n个巧克力盒子,他希望把这n个盒子全都填满,要求每种盒子中只能包含有一种巧克力,巧克力可以有剩余,如果能填满,就输出第一种巧克力用了多少个盒子,并且输出盒子的序号,如果不能就输出Impossible to distribute
0,1背包
m[s]:表示s这个数能否被填满
m[s]=m[s]|m[s-d[i]]
求出第一种巧克力最多能用掉多少个后,直接判断第2种巧克力的量和所需要的总量比较大小即可
#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
int main()
{
int m,l;
while(scanf("%d%d",&m,&l)!=EOF&&(m||l)){
int n;scanf("%d",&n);
int sum=0;
int d[2*maxn];
for (int i=0;i<n;i++){
scanf("%d",&d[i]);
sum+=d[i];
}
if (sum>(m+l)){
printf("Impossible to distribute\n");
continue;
}
int ms[2*maxn];
memset(ms,0,sizeof(ms));
int mm=0;
ms[0]=1;
int pre[2*maxn]={0};
for (int i=0;i<n;i++){
for (int s=m;s>=d[i];s--){
if (!ms[s]&&ms[s-d[i]]){
ms[s]=1;
pre[s]=s-d[i];
mm=mm>s?mm:s;
}
}
}
int used[2*maxn];
memset(used,0,sizeof(used));
int anss=0;
for (int i=mm;i!=0;i=pre[i]){
int data=i-pre[i];
for (int is=0;is<n;is++){
if (d[is]==data&&used[is]==0){
anss++;
used[is]=1;
break;
}
}
}
if (sum-mm>l){
printf("Impossible to distribute\n");
}
else
{
printf("%d",anss);
for (int i=0;i<n;i++){
if (used[i]){
printf(" %d",i+1);
}
}
printf("\n");
}
}
return 0;
}