nyoj546 Divideing Jewels (动态规划+优化||搜索+剪枝)

题意:给你n个宝珠,然后给宝珠个价值,价值范围【1,10】,能不能均分给两个人。

输入的数据:价值分别为1,2,3...10的有多少个。

这道题和队友做了好久最终在结束前5分钟AC。。第一次简单的动规结果TLE

不过和队友认为一定是动规。就在想如何优化,想到如果某个价值的个数有偶数个就不判断,奇数个就存入数组。

结果还是wr...我们不放弃啊、、、为就想着写几组数组,当0 2 0 1 0 0 0 0 0 0 输出结果为不能,显然答案是能的。

还剩下不到20分钟了。这个时候就是靠感觉了,直接就写如果某个价值的个数为偶数个只存两个,为奇数个存一个  。

结果AC   那种AC的开心 让人愉悦大笑

代码:

 
#include <stdio.h>
#include <string.h>
int a[25],dp[10005],q,maxsum;
int main()
{
	int sum,x,step=1,max;
	while(1)
	{
		memset(dp,0,sizeof(dp));
		memset(a,0,sizeof(a));
		sum=q=maxsum=max=0;
		for(int i=0;i<10;i++)
		{
			scanf("%d",&x);
			if(x==0)//如果为0,sum++
			{
				sum++;
				continue;
			}
			if(x%2)//如果x为奇数,maxsum记录所有x的和
			a[q++]=i+1,maxsum+=i+1;
			else//如果x为偶数
			{
				a[q++]=i+1;
				a[q++]=i+1;
				maxsum=maxsum+2*(i+1);
			}
		}
		if(sum==10)//如果有10个0
		break;
		if(maxsum%2)//如果maxsum不能被2整除  肯定不能均分
		{
			printf("#%d:Can't be divided.\n",step++);
			printf("\n");
			continue;
		}
		for(int i=0;i<q;i++)//动规
		for(int j=maxsum/2;j>=a[i];j--)
		{
			dp[j]=dp[j];
			if(dp[j]<dp[j-a[i]]+a[i])
			dp[j]=dp[j-a[i]]+a[i];
			if(max<dp[j])
			max=dp[j];
		}
		if(max==maxsum/2)//如果max等于maxsum的一半 能均分
		printf("#%d:Can be divided.\n",step++);
		else
		printf("#%d:Can't be divided.\n",step++);
		printf("\n");
	}
	return 0;
}                
 
 //搜索方法,同样的原理
#include <stdio.h>
#include <string.h>
int a[25],flag,visit[25],q,maxsum;
void dfs(int star,int sum)
{
	if(sum == maxsum/2)
	{
		flag=1;
		return ;
	}
	if(sum>maxsum/2)
	return ;
	for(int pre=0,i=star;i<q;i++)//pre优化,如果两个值相等
	{
		if(!visit[i]&&a[i]!=pre)
		{
			pre=a[i];
			visit[i]=1;
			sum+=a[i];
			dfs(star+1,sum);
			if(flag)
			break;
			sum-=a[i];
			visit[i]=0;
		}
	}
	if(flag)
	return ;
}
int main()
{
	int sum,x,step=1;
	while(1)
	{
		memset(visit,0,sizeof(visit));
		memset(a,0,sizeof(a));
		sum=q=maxsum=flag=0;
		for(int i=0;i<10;i++)
		{
			scanf("%d",&x);
			if(x==0)
			{
				sum++;
				continue;
			}
			if(x%2)
			a[q++]=i+1,maxsum+=i+1;
			else
			{
				a[q++]=i+1;
				a[q++]=i+1;
				maxsum=maxsum+2*(i+1);
			}
		}
		if(sum==10)
		break;
		if(maxsum%2)
		{
			printf("#%d:Can't be divided.\n",step++);
			printf("\n");
			continue;
		}
		dfs(0,0);
		if(flag)
		printf("#%d:Can be divided.\n",step++);
		else
		printf("#%d:Can't be divided.\n",step++);
		printf("\n");
	}
	return 0;
}                


你可能感兴趣的:(546,nyoj,nyoj546)