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;
}                
时间: 2024-11-09 00:57:57

nyoj546 Divideing Jewels (动态规划+优化||搜索+剪枝)的相关文章

Divideing Jewels(nyoj546)(多重背包+二进制优化)

Divideing Jewels 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 Mary and Rose own a collection of jewells. They want to split the collection among themselves so that both receive an equal share of the jewels. This would be easy if all the jewels had the same

poj 1054 The Troublesome Frog (暴力搜索 + 剪枝优化)

题目链接 看到分类里是dp,结果想了半天,也没想出来,搜了一下题解,全是暴力! 不过剪枝很重要,下面我的代码 266ms. 题意: 在一个矩阵方格里面,青蛙在里面跳,但是青蛙每一步都是等长的跳, 从一个边界外,跳到了另一边的边界外,每跳一次对那个点进行标记. 现在给你很多青蛙跳过后的所标记的所有点,那请你从这些点里面找出 一条可能的路径里面出现过的标记点最多. 分析:先排序(目的是方便剪枝,break),然后枚举两个点,这两个 点代表这条路径的起始的两个点.然后是三个剪枝,下面有. 开始遍历时,

剪枝算法--优化搜索(转载)

转载于:http://princetonboy.ycool.com/post.2805302.html [摘要]本文讨论了搜索算法中“剪枝”这一常见的优化技巧. 首先由回溯法解决迷宫问题展开论述,介绍了什么是剪枝; 而后分析剪枝的三个原则正确.准确.高效,并分别就剪枝的两种思路:可行性剪枝及最优性剪枝,结合例题作进一步的阐述; 最后对剪枝优化方法进行了一些总结. [关键字]搜索.优化.剪枝.时间复杂度 引论 在竞赛中,我们有时会碰到一些题目,它们既不能通过建立数学模型解决,又没有现成算法可以套用

1D1D动态规划优化

1D1D动态规划优化 1D/1D 动态规划优化初步所谓1D/1D 动态规划,指的是状态数为O(n),每一个状态决策量为O(n)的动态规划方程.直接求解的时间复杂度为O(n2),但是,绝大多数这样的方程通过合理的组织与优化都是可以优化到O(nlogn)乃至O(n)的时间复杂度的.这里就想讲一讲我对一些比较初步的经典的优化方法的认识.本文中不想进行过多的证明与推导,主要想说明经典模型的建立.转化与求解方法.由于本人认识与水平相当有限,如果出现什么错误与疏漏,还请大牛多多指正.另外,也希望大牛们更多地

nyoj 546——Divideing Jewels——————【dp、多重背包板子题】

Divideing Jewels 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 Mary and Rose own a collection of jewells. They want to split the collection among themselves so that both receive an equal share of the jewels. This would be easy if all the jewels had the same

『生日蛋糕 搜索剪枝』

Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为N×π的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱.当i < M时,要求Ri > Ri+1且Hi > Hi+1. 由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小. 令Q = S×π请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小.(除Q外,以上所

【搜索剪枝】HDU 5469 Antonidas

通道 题意:给出1字母树,询问一字符串是否出现在该树中 思路:直接搜索剪枝,有人点分治?写了几发都T了..有人会了教我? 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Edge { int v, nxt; Edge () { } Edge (int _v, int _n) { v = _v, nxt = _n; } }; const in

USACO/fence8 迭代加深搜索+剪枝

题目链接 迭代加深搜索思想. 枚举答案K,考虑到能否切出K个木头,那么我们当然选最小的K个来切. 1.对于原材料,我们是首选最大的还是最小的?显然,首选大的能够更容易切出,也更容易得到答案. 2.对于目标木头,我们是优先得到最大的还是最小的?显然,由于K个木头我们都要得到,那么当然先把最大的(最难得到的)先得到,这种搜索策略更优. 3.假设总原材料为all,前K个木头总和为sum,那么all-sum就是这一次切割过程中能[浪费]的最大数目.对于一个切剩下的原材料,若它比最小的目标木头还要小,则它

hdu 5887 搜索+剪枝

Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 687    Accepted Submission(s): 145 Problem Description Collecting one's own plants for use as herbal medicines is perhaps one of t