Poj 1014 题解

12 篇文章 0 订阅

第一次发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>




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值