一个基础背包问题的变形
有机结合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();
}