1071新年趣事之打牌——vijos

一个基础背包问题的变形

有机结合01背包(类似)   装箱问题

个人觉得函数名有点赞。。


先跑一个装箱问题
判断能否输出-1 或者 0 
只是将原来装箱问题的bool型换成int   记录下到达当前状态的方案数量 

然后再来一个01 背包  (要压空间  不然mle) 

只用记录下第一种就可以printf  exit 了


#include<cstdio>
#include<algorithm>
#define ul(i,j,k) for(int i=j;i<=k;i++)
#define dl(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
int com[100*1000+10];
int le,n;
int w[100+10];
int tot;
struct HAVE
{
	int a[100+10];
	int cnt;
}have[100000];
void readdata()
{
	scanf("%d%d",&le,&n);
	ul(i,1,n)
	{
		scanf("%d",&w[i]);
		tot+=w[i];
	}
	le=tot-le;
	if(le<0)
	{
		printf("0\n");
		exit(0);
	}
}
void o_o()
{
	com[0]=1;
	ul(i,1,n)
	dl(j,tot,w[i])
	if(com[j-w[i]])
	com[j]+=com[j-w[i]];
	if(com[le]==1)
	return;
	if(com[le]>1)
	{
		printf("-1");		
		exit(0);
	}
	if(com[le]==0)
	{
		printf("0");
		exit(0);
	}
}
bool uu[100*1000+10];
void bag()
{
	uu[0]=1;
	ul(i,1,n)
	dl(j,le,1)
	{
		if(j-w[i]<0)
		continue;
		if(uu[j-w[i]])
		{
			uu[j]=1;
			have[j]=have[j-w[i]];
			have[j].a[++have[j].cnt]=i;
			if(j==le)
			{
				ul(l,1,have[le].cnt)
				printf("%d ",have[le].a[l]);
				exit(0);
			}
		}
	}
}
void solve()
{
	o_o();
	bag();
}
int main()
{
	readdata();
	solve();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值