zoj 1520 Duty Free Shop

题意: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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值