第一次发poj,原百度空间已经放弃了。
还是贴个网址吧,容易找一点。
http://hi.baidu.com/scqmysgfqrajrtr
一道多重背包的题。
一开始直接背包
Code:
<span style="font-family:SimSun;font-size:14px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[7];int t=0;
bool v[21000];
void Solve()
{
int ans=0;
for(int i=1;i<=6;i++)
ans+=i*a[i];
if(ans%2==1)
{
printf("Collection #%d:\n",t);
printf("Can't be divided.\n",t);
}
else
{
memset(v,0,sizeof(v));
v[0]=true;
for(int i=1;i<=6;i++)
for(int j=1;j<=a[i];j++)
for(int k=ans;k>=i;k--)
if(v[k-i])
v[k]=true;
if(v[ans/2]==1)
{
printf("Collection #%d:\n",t);
printf("Can be divided.\n",t);
}
else
{
printf("Collection #%d:\n",t);
printf("Can't be divided.\n",t);
}
}
}
int main()
{
while(1)
{
t++;
bool bk=false;
for(int i=1;i<=6;i++)
{
scanf("%d",&a[i]);
if(a[i]!=0) bk=true;
}
if(bk==false) break;
else
{
Solve();
}
}
return 0;
}</span>
直接裸着dp,无疑,极端数据立刻88
然后就是二进制了
比如36*6的
就可以分成1*6,2*6,4*6,8*6,16*6,3*6
这样的话,直接dp这几种情况就好了。
为什么呢?
因为7*6=1*6+2*6+4*6
这样就可以组成了。
之后就ac了,感谢wph
Code:
<span style="font-family:SimSun;font-size:14px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int sum=0;
int a[7]; int t=0;
int p[11000]; int ls=0;
int bit[22];
bool v[61000];
void Solve()
{
memset(p,0,sizeof(p));
for(int i=1;i<=20;i++) bit[i]=1<<(i-1);
for(int i=1;i<=6;i++)
{
for(int j=1;a[i]>=bit[j];j++)
{
p[++ls]=bit[j]*i;
a[i]-=bit[j];
}
p[++ls]=a[i]*i;
}
memset(v,0,sizeof(v));
v[0]=1;
for(int i=1;i<=ls;i++)
{
for(int j=sum/2;j>=p[i];j--)
{
if(v[j-p[i]])
{
v[j]=true;
if(j==sum/2)
{
printf("Collection #%d:\n",t);
printf("Can be divided.\n");
return ;
}
}
}
}
printf("Collection #%d:\n",t);
printf("Can't be divided.\n");
}
int main()
{
while(1)
{
t++;
bool bk=false; sum=0;
for(int i=1;i<=6;i++)
{
scanf("%d",&a[i]); sum+=a[i]*i;
if(a[i]!=0) bk=1;
}
if(bk==0)
{
printf("\n");
break;
}
if(sum%2==1)
{
printf("Collection #%d:\n",t);
printf("Can't be divided.\n");
}
else Solve();
printf("\n");
}
return 0;
}</span>