【搜索\位集合】送给圣诞夜的贺卡

描述 Description 
 每年的12月24日,是圣诞老人忙碌的日子,也只有这一天,他才会忙碌起来。面对着将要来临的宁静的夜晚,是一种怎样的幸福和安宁感。作为圣诞老人的第一件事,就是需要为世界各地的孩子们写上贺卡,带上自己的祝福和礼品送给他们。毕竟,世界上那么多可爱的孩子,要给他们每一个人写一封贺卡,单凭自己的力量是不足以完成的。
  众所周知,一直陪伴在圣诞老人身边的是快乐的小精灵们。他们为圣诞老人而工作,其实是一个很乐意的事情。冰天雪地的北极,是他们的家,是圣诞老人的家。圣诞老人一直以来对于贺卡的书写非常重视,他也一直请一些优秀的小精灵们去帮助他完成这件事……
  12月24日早上7点钟。北极圣诞区开了一个会,会议由圣诞老人主持,在会的其他都是小精灵们,他们似乎都非常高兴,原因是等待圣诞老人的一份名单。这份名单里面的人都是这些小精灵们,一共n有个小精灵。这n个小精灵是圣诞老人根据这一年大家的表现状况(比如说谁吃饭吃得最多、谁调制的巧克力最好吃、谁的笑声最大、谁最不喜欢哭等等因素)而制定的预选的书写贺卡者名单。
  圣诞老人一个一个字,饱含激情地念出了每一个预选的小精灵。鼓掌……
  可是,接下来。并不是这个预选名单里面的所有小精灵都可以参加贺卡书写这个合作性任务。因为在以前的贺卡书写合作任务中,有一些小精灵们因为某些原因而对书写的格式和书写的字体喋喋不休。所以尽量避免这种情况发生,圣诞老人必须从预选名单中选出m(1<=m<=n)个小精灵来完成这项任务。可是……每一个小精灵的贺卡书写质量又有所不同……
  圣诞老人想了想,他觉得应该在其中选择m个小精灵,使得这m个小精灵中任意两个在曾经的贺卡书写合作任务中没有发生过矛盾冲突,并且需要这m个小精灵的书写质量的总合S最高。
   
   
 输入格式 Input Format 
 第一行一个数n。
  第二行n个数,第i个数代表预选名单中第i号小精灵的书写质量(均为非负整数)。
  接下来有若干行,每行两个不同的非负整数x和y,表示预选名单中第x号和第y号的小精灵曾经在贺卡书写合作任务中发生过冲突。
   
   
  输出格式 Output Format 
 第一行一个数S。
   
   
  样例输入 Sample Input 
 
   
   
  样例输出 Sample Output 
 
   
   
  时间限制 Time Limitation 
 各个测试点1s
   
   
  注释 Hint 
 1<=n<=50,1<=x,y<=n
友情提示:可能没有矛盾关系,使用SEEKEOF和EOF都有出错的可能,请加条件判断。



这是一个01枚举的2^n的搜索。


根据矛盾关系,我们可以把和其中一个点的冲突关系抽象为一个集合,集合中的元素是与它有冲突的点。

再用另一个集合,表示当前搜索到的位置选取了哪些点。后者与当前要判断选择与否的点它的“冲突对象“集合如果无交集,则可以选择该点。

而数据范围小于等于50,很适合使用位集合,果断摒弃O(n)的数组的方法,于是我们就用O(1)实现了有无冲突的判断。

然后我稍微考虑了一下最优性剪枝。如果现在已有的权值和加上剩下能获得的最大权值和仍然小于当前最优解,则果断放弃。

第一次交TLE80。


然后,根据以上最优性剪枝,我们可以通过排序(这是一种普遍的最优性剪枝上的优化),将大的放在前面。

另外,看了题解。。。题解里还加了一个剪枝,如果和其他点没有冲突的点必须选择。。


然后就过了。


这是一个位集合使用的好范例。

#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using std::sort;

typedef long long ll;
long ans = 0;
long n;

ll conflict[60];
long v[60];
long sum[60];
long hash[60];
bool wc[60];

long getint()
{
	long rs=0;bool sgn=1;char tmp;
	do tmp = getchar();
	while (!isdigit(tmp)&&tmp!='-');
	if (tmp=='-'){tmp=getchar();sgn=0;}
	do rs=(rs<<3)+(rs<<1)+tmp-'0';
	while (isdigit(tmp=getchar()));
	return sgn?rs:-rs;
}

void dfs(long u,ll s,long c)
{
	if (u == n + 1)
	{
		if (c > ans)
			ans = c;
		return;
	}

	if (c + sum[u] <= ans)
		return;

	if (wc[u])
		dfs(u+1,s,c);
	if (!(conflict[u] & s))
	{
		dfs(u+1,s | (1ll<<(u-1)),c+v[u]);
	}
}

struct node
{
	long v;
	long i;
	bool operator<(const node& n2)const
	{
		return v>n2.v;
	}
};
node tmp[60];

int main()
{
	freopen("christmas.in","r",stdin);
	freopen("christmas.out","w",stdout);
	n = getint();
	for (long i=1;i<n+1;i++)
	{
		tmp[i].i = i;
		tmp[i].v = getint();
	}
	sort(tmp+1,tmp+1+n);
	for (long i=1;i<n+1;i++)
	{
		hash[tmp[i].i] = i;
		v[i] = tmp[i].v;
	}
	for (long i=n;i>0;i--)
	{
		sum[i] = sum[i+1]+v[i];
	}

	long a,b;
	while (scanf("%ld%ld",&a,&b)==2)
	{
		a = hash[a];
		b = hash[b];
		conflict[a] |= 1ll<<(b-1);
		conflict[b] |= 1ll<<(a-1);
		wc[a] = true;
		wc[b] = true;
	}

	dfs(1,0,0);

	printf("%ld",ans);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
python圣诞节贺卡是一种可以通过代码生成的贺卡,可以在代码运行时展示出动画界面和雪花飘落效果。你可以将这个贺卡送给你的朋友,向他们表达圣诞节的祝福。代码的实现方式可以根据个人的喜好和技能来选择,可以使用Python中的图形库和动画函数来实现贺卡的效果。下面是一个示例代码,你可以根据需求进行修改和优化: ``` import turtle # 设置画布大小和背景颜色 turtle.setup(800, 600) turtle.bgcolor("black") # 设置画笔属性 turtle.pensize(3) turtle.color("white") turtle.speed(0) # 绘制圣诞树 def draw_tree(): turtle.penup() turtle.goto(-100, -200) turtle.pendown() turtle.setheading(90) turtle.color("green") turtle.begin_fill() turtle.forward(200) turtle.right(120) turtle.forward(200) turtle.right(120) turtle.forward(200) turtle.end_fill() # 绘制雪花 def draw_snowflake(): for _ in range(8): for _ in range(4): turtle.forward(50) turtle.backward(50) turtle.right(90) turtle.right(45) # 绘制祝福语 def draw_greetings(): turtle.penup() turtle.goto(-100, 0) turtle.pendown() turtle.color("red") turtle.write("Merry Christmas!", align="center", font=("Arial", 40, "bold")) # 控制雪花飘落 def snowfall(): while True: for flake in snowflakes: flake.goto(flake.xcor(), flake.ycor() - 2) if flake.ycor() < -300: flake.goto(flake.xcor(), 300) # 生成雪花 def generate_snowflakes(num): snowflakes = [] for _ in range(num): flake = turtle.Turtle() flake.shape("turtle") flake.color("white") flake.shapesize(0.1) flake.speed(0) flake.penup() x = random.randint(-300, 300) y = random.randint(0, 300) flake.goto(x, y) snowflakes.append(flake) return snowflakes # 主函数 def main(): draw_tree() draw_greetings() snowflakes = generate_snowflakes(30) snowfall() # 运行主函数 main() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值