【题解】洛谷P2831 愤怒的小鸟(搜索 状压)

题解:洛谷 P2831 [NOIP 2016 提高组] 愤怒的小鸟 这款神奇游戏的每个关卡对 Kiana 来说都很难,所以 Kiana 还输入了一些神秘的指令,使得自己能更轻松地完成这个这个游戏。个关卡,现在 Kiana 想知道,对于每一个关卡,至少需要发射多少只小鸟才能消灭所有的小猪。处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟, 小鸟们的飞行轨迹均为形如。输出的每一行包含一个正整数,表示相应的关卡中,消灭所有小猪最少需要的小鸟数量。,分别表示该关卡中的小猪数量和 Kiana 输入的神秘指令类型。而这个游戏的目的,就是通过发射小鸟消灭所有的小猪。 阅读详情
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int t;
int m1,m2;
struct pig
{
	double x;
	double y;
}a[20];
int line[8010][25];
bool zhu[20];
int ans,tot;
int n,m;
bool same(double x1,double x2)
{
	if(abs(x1-x2)<1e-8) return true;
	else return false;
}
void add(int x,int y)
{
	line[x][++line[x][0]]=y;
}
void swapp(int x,int y)
{
	for(int i=0;i<20;i++)
	{
		swap(line[x][i],line[y][i]);
	}
}
void dfs(int x,int cnt,int now) //bird pig now_line
{
	if(cnt==n) ans=min(ans,x);
	if(x>=ans-1) return ;
	bool hs[20]={0};
	for(int i=now;i<=tot&&x<ans-1;i++)
	{
		int cntt=0;
		for(int j=1;j<=line[i][0];j++)
		{
			if(zhu[line[i][j]]==false)
			{
				zhu[line[i][j]]=true;
				hs[line[i][j]]=true;
				cntt++;
			}
		}
		if(x==0&&cntt<m2) break;
		if(cntt>0)
		{
			dfs(x+1,cnt+cntt,i+1);
			for(int j=1;j<=line[i][0];j++)
			{
				if(hs[line[i][j]]==true)
				{
					zhu[line[i][j]]=false;
					hs[line[i][j]]=false;
				}
			 } 
		}
	}
}
int main()
{
//	freopen("angrybirds.in","r",stdin);
//	freopen("angrybirds.out","w",stdout);
	scanf("%d",&t);
	while(t--)
	{
		
		scanf("%d%d",&n,&m);
		m1=n,m2=1;
		if(m==1) m1=(n+2)/3+1;
		if(m==2) m2=max(m2,n/3);
		for(int i=1;i<=n;i++)
		{
			cin>>a[i].x>>a[i].y;
		}
		tot=0;
		memset(line,0,sizeof(line));
		for(int i=1;i<=n;i++)
		{
			bool flag=false;
			for(int j=i+1;j<=n;j++)
			{
				double ka=(a[j].x*a[i].y-a[i].x*a[j].y)/(a[i].x*a[j].x*(a[i].x-a[j].x));
				if(ka>=0) continue;
				double kb=(a[i].y/a[i].x)-ka*a[i].x;
				tot++;
				add(tot,i);
				add(tot,j);
				flag=true;
				for(int k=1;k<=n;k++)
				{
					if(k!=i&&k!=j)
					{
						if(same(ka*a[k].x*a[k].x+kb*a[k].x,a[k].y))
						{
							add(tot,k);
						}
					}
				}
			}
			if(flag==false)
			{
				tot++;
				add(tot,i);
			}
		}
		for(int i=1;i<=tot;i++)
		{
			for(int j=i+1;j<=tot;j++)
			{
				if(line[j][0]>line[i][0])
				{
					swapp(i,j);
				}
			}
		}
		ans=m1;
		memset(zhu,0,sizeof(zhu));
		dfs(0,0,1);
		printf("%d\n",ans);
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

(以上为70分搜索代码)

观察一下数据大小我们可以知道可以利用搜索解决。我们先设连接任意两点(或者无解时是一点)有一条抛物线,编号后枚举剩下的其他点,看看这条线能不能过那些点(至于具体实现可以解二元一次方程组)。连好线后为了方便搜索我们可以将通过小鸟多的线放在前面,然后进行搜索。注意我们可以一开始读入n,m时就记录m1与m2值,这样我们在搜索当中可以剪枝,估计题目给m的意思也是为了方便搜索。注意记录状态还有回溯,而且要防止爆精度。这样可以得到70分

满分的做法是状压dp。我们可以用二进制位上1的数量记录猪的数量(也是这条抛物线可以干掉猪的数量),1的位置代表猪的编号,这样最多我们有2^18种情况。初始化dp[0]为0记录用的小鸟的数量,dp内的数代表该情况下所有位都为1,所以我们的目标是求得dp[(1<<n)-1]。可以得到状态转移方程dp[i|bird[j]]=min(dp[i|bird[j]],dp[i]+1)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int INF=0x3f3f3f3f;
int t;
int m1,m2;
struct pig
{
	double x;
	double y;
}a[20];
int line[8010][25];
bool zhu[20];
int ans,tot;
int n,m;
bool same(double x1,double x2)
{
	if(abs(x1-x2)<1e-8) return true;
	else return false;
}
int dp[1<<18]; //2^18
int bird[400];
int main()
{
//	freopen("angrybirds.in","r",stdin);
//	freopen("angrybirds.out","w",stdout);
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		m1=n,m2=1;
		if(m==1) m1=(n+2)/3+1;
		if(m==2) m2=max(m2,n/3);
		for(int i=1;i<=n;i++)
		{
			cin>>a[i].x>>a[i].y;
		}
		tot=0;
		for(int i=1;i<=n;i++)
		{
			bool flag=false;
			for(int j=i+1;j<=n;j++)
			{
				double ka=(a[j].x*a[i].y-a[i].x*a[j].y)/(a[i].x*a[j].x*(a[i].x-a[j].x));
				if(ka>=0) continue;
				double kb=(a[i].y/a[i].x)-ka*a[i].x;
				flag=true;
				bool bb[30]={0};
				bb[i]=true;
				bb[j]=true;
				for(int k=i+1;k<=n;k++)
				{
					if(k!=i&&k!=j)
					{
						if(same(ka*a[k].x*a[k].x+kb*a[k].x,a[k].y))
						{
							bb[k]=true;
						}
					}
				}
				int ans=0;
				for(int k=1;k<=n;k++)
				{
					ans*=2;
					if(bb[k]==true)
					{
						ans++;
					}
				}
				bird[++tot]=ans;
			}
			if(flag==false)
			{
				int ans=0;
				for(int k=1;k<=n;k++)
				{
					ans*=2;
					if(k==i)
					{
						ans++;
					}
				}
				bird[++tot]=ans;
			}
		}
		memset(dp,INF,sizeof(dp));
		dp[0]=0;
		for(int i=0;i<(1<<n);i++)
		{
			for(int j=1;j<=tot;j++)
			{
				dp[i|bird[j]]=min(dp[i|bird[j]],dp[i]+1);
			}
		}
		cout<<dp[(1<<n)-1]<<endl;
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

 

麒麟操作系统安装达梦数据库ARM版 Linux安装达梦数据库ARM版 阅读详情

相关推荐

Unity URP项目里Post Processing死活没效果?别慌,这5个坑我帮你踩过了

本文详细解析了Unity URP项目中Post Processing效果失效的五大常见问题,包括渲染管线配置冲突、Volume作用域误判、摄像机参数漏配、Layer层级冲突和Profile引用异常。通过实际项目案例和代码示例,提供专业级解决方案,帮助开发者快速排查并修复后处理效果不生效的问题。

weixin_33721427的博客 333

洛谷 P2831 愤怒的小鸟

一看就是道毒瘤题 两位数的数据范围,一看不是暴搜枚举就是状压了 我们考虑状压啦 预处理出O(n2)O(n^2)O(n2)条抛物线各自串起来哪几只猪,然后位运算暴算一通 先推个抛物线公式 {x12a+x1b=y1x22a+x2b=y2\begin{aligned}\begin{cases} {x_1}^2a+x_1b=y_1\\ {x_2}^2a+x_2b=y_2\\ \end{cases}\end...

MZW_BG的博客 219

定时移动鼠标点击鼠标,防止电脑息屏的vba脚本

定时移动鼠标,使系统始终处于激活状态,防止系统息屏。

panfei263031的博客 5932

洛谷【P2831】愤怒的小鸟 (NOIP 2016 D2T3)

题目描述Kiana最近沉迷于一款神奇的游戏无法自拔。简单来说,这款游戏是在一个平面上进行的。有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如y=ax2+bxy=ax^2+bx的曲线,其中a,b是Kiana指定的参数,且必须满足a<0。当小鸟落回地面(即x轴)时,它就会瞬间消失。在游戏的某个关卡里,平面的第一象限中有n只绿色的小猪,其中第i只小猪

George__Yu的博客 1156

GeoServer改造Springboot源码一(公共部分)

今天开始开启关于GeoServer的一个全新系列,主要是把改造Springboot后的详细代码粘贴出来,此文应配合《》系列共同阅读,按照前系列的时间顺序结合此系列的源码展示可以快速构建GeoServer功能的二次封装的后端系统。

龙井的专栏 1902

小龙虾们的好伙伴专栏导航

本文系统解析了OpenClaw技术架构,包括Channel层和网关层的设计实现,并与AgentSkills等技术方案进行对比。同时提供了OpenClaw的系列实用指南,涵盖小龙虾培养、客户资源管理、系统自动化巡检以及技术趋势助手构建等应用场景,帮助用户从零成本入门到高效落地应用,实现业务全流程自动化管理。

wend的博客 214

【洛谷题解/NOIP2016提高组】P2831 愤怒的小鸟

NOIP2016提高组愤怒的小鸟题解。

lovely_cyqの小窝 631

Spring AI Alibaba实战训练营-20 基于注解驱动的MCP快速开发入门指南

本文详细讲解如何使用SpringAiAlibaba快速开发基于注解驱动的MCP应用。文章详细介绍了MCP协议并且重点介绍了Spring AI通过注解驱动的开发方式简化MCP服务开发。具体包括服务端和客户端的注解使用、城市最新时间查询MCP项目结构概览(服务端和客户端模块)以及环境配置要求。

program哲学 295

【洛谷 P2831】 愤怒的小鸟【状态压缩】

解题思路 预处理一个 st[i][j] 表示经过 i,j 两点的抛物线能经过的所有点的集合,具体做法就是枚举出两个点,分别算出对应的a,b,然后再枚举点,判断是否再当前线上出现过。 如何求a,b: 设dp[S]表示以被消灭的状态为S时,需要多少只鸟。 一个奇妙的初始化v[i]v[i]v[i],存的是是iii这个状态内第一个0的位置,也就是我们做dp的起始位置。 首先,我们开始操作的点是start[i],我们先将它预先转移一下,s=start[i],假设s这头猪被打掉的状态等于i被打掉的状态的最...

在人间贩卖声音 273

zabbix系列:内存VM.MEMORY.SIZE监控之total、free、pused、available 参数说明

free -m buffer是即将要被写入磁盘的,而cache是被从磁盘中读出来的. zabbix Web total:1046/1024=1.02G Available:216/1046=20.65% zabbix参数 total- 总物理内存. free- 可用内存. active- 内存当前使用或最近使用,所以它在RAM中。 inactive- 未使用内存. wired- 被标记为始终驻留在RAM中的内...

NIO4444 5668

NVIDIA Isaac GR00T N1.5 人形机器人强化学习入门教程(四)Lerobot、宇树 G1 等不同形态机器人微调教程

本笔记本是一份关于如何在新的数据集上对GR00T-N1预训练模型进行微调的教程。

2506_90492529的博客 1667

洛谷 P2831 愤怒的小鸟题解

首先我们先思考抛物线本身,我们应用贪心的思想,我们一定要选出可以至少打中一个小猪的抛物线(不然没有任何意义);然后我们定义一个数组selected表示第tp根抛物线击中状态(如selected[2] = 1001 表示第2跟抛物线击中了第4,1个小猪);首先我们定义dp[i]为在状态i时,使用最小的小鸟数量;那么什么是状态呢,状压dp是子集上的动态规划,i 此处使用二进制存储如n=4是,1100表示击中第四第三只猪的状态。4. 答案就是最终状态对应的dp数组值,可以使用maxn = 1<<n - 1。

2302_80063488的博客 405

视频压缩的工作原理

当你正在观看你最喜欢的节目,出现缓冲的时候,这是什么原因?当 Wi-Fi 带宽不足以下载传输视频流所需的数据时,就会发生缓冲。也有可能是视频网站发布了未压缩版本的视频文件,因此视频文件太大而无法流畅地流式传输。在高清模式下,图像分辨率为1080x1920像素,如果我们想象一个视频由许多这些图像组成,称为帧,那么 Wi-Fi 连接必须多快才能播放24帧/秒?答案是超1000兆,没错。由于每一帧都是48兆比特的数据,它实际上需要48×24每秒兆比特 (Mbps) 以观看视频24帧/秒。

学以致用 知行合一 1281

洛谷P2831 NOIP2016 愤怒的小鸟

洛谷P2831 NOIP2016 愤怒的小鸟题目思路一些小问题精度:抛物线解析式:tips:代码我的(1.cpp)自测程序(compare.cpp) 题目 传送门 思路 个人感觉我的思路并不是很优 m貌似没什么用(可能是部分分),直接忽略 但是看到n最大才去到18,不是状压就是爆搜,我采用的是DFS维护状压DP的转移(其实有点像记忆化搜索) 注意:为了方便状压,以下小猪的编号从0~n-1 设状态k二进制下第i为表示:第i只小猪的消灭情况0:没消灭,1:消灭,f[k]表示状态为k时最少用的小鸟数量 状态转移:

weixin_46304837的博客 335

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

P2831 愤怒的小鸟 题解

博客园同步 原题链接 简要题意: 平面直角坐标系的第一象限有若干绿猪,小鸟要通过若干条函数解析线来消灭它们。每个小鸟可以把所有 y=ax2+bx(a<0)y=ax^2 + bx (a<0)y=ax2+bx(a<0) 上的 (x,y)(x,y)(x,y) 的所有绿猪消灭,当然没有绿猪就是白走。问最少多少次后可以消灭所有的绿猪。TTT 组数据。 前记 实际上,之前写过一篇 骗分导论,里面有点口出狂言,既然自己说了能 60pts60pts60pts 那还不来填坑? 算法一 对于 70%70 \

bifanwen的博客 397

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【luogu P2831 愤怒的小鸟】 题解

题目链接:https://www.luogu.org/problemnew/show/P2831 写点做题总结:dp,搜索,重在设计状态,状态设的好,转移起来也方便。 对于一条抛物线,三点确定。(0,0)是固定的,所以我们一条抛物线要用两只猪确定。再多的猪就只能用来判断是不是在这条抛物线上了。 于是我们把猪分成两种:在已有方程里的猪,单独的猪还没有确定方程。 那么对于一只猪,就会有被以前...

157

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【niop2016】【luogu2831】愤怒的小鸟 [状压dp][搜索]

luogu2831 主要和luogu第一篇题解思路一样 第二个优化真的hei牛逼 若令x 为满足 S&(1<<(x−1))=0 的最小正整数,则由S扩展的转移的所有线都要经过 x 先打1 4再打2 2和先打2 3再打 1 4一样 如果这一次转移不打 x ,那以后还要再回过头来打 x 这就是多余的转移。 因为经过 x 的线数量是 nnn ,所以每次转移涉及...

weixin_30325793的博客 138

洛谷P2831 [NOIP2016] 愤怒的小鸟【状压DP】

题目描述 Kiana 最近沉迷于一款神奇的游戏无法自拔。 简单来说,这款游戏是在一个平面上进行的。 有一架弹弓位于(0,0)(0,0) (0,0)处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如y=ax2+bxy=ax2+bx y=ax^2+bx的曲线,其中a,ba,b a,b是Kiana 指定的参数,且必须满足a&amp;amp;amp;amp;amp;amp;amp;amp;lt;0a&amp;amp;amp;amp;amp;amp;amp;am

niiick 327

状压dp学习(1)

写出来了代码,结果居然加起来跑了好几秒钟,看一下别人都是几百毫秒,瞬间感到很羞耻。seriesijseriesij也可以记忆化。这大概会省很多时间吧,因为我原来的代码只有一个dpdpdp采取了记忆化,遇到相同的iji,jij,确实每次都需要现场求seriesijseriesij。但是鉴于我太懒就先不写代码了,知道这一点就行了吧。当任取两个豪猪,构成的抛物线开口都向上的时候,可以直接返回当前豪猪数量的。

wr114514的博客 870

洛谷P2831 愤怒的小鸟

一道还算可以的DP题?

bcr_233的博客 317

洛谷p2831愤怒的小鸟

原题 每个猪的位置不同,所以不能简单的表示出状态,all[i]表示第i个抛物线打掉了哪些猪,其值本身存储状态(二进制),只需要找所有有用的抛物线,然后状压f[i]表示i状态下最少用掉的鸟,转移方程见代码。 其中的m可以用来优化。代码虽然长,但是比较好懂。 #include #include #include #include #include #include using namespace

Tekim的博客 547

[洛谷P2831]愤怒的小鸟

状压DP。没了。

七代目鸽影 292

洛谷P2831 愤怒的小鸟 (NOIp2016)

状压DP

forezxl的博客 1206

2018.11.02 洛谷P2831 愤怒的小鸟(状压dp)

传送门 状压一眼题。 直接f[i]f[i]f[i]表示未选择状态为iii时的最小次数。 然后考虑现在怎么转移。 显然可以直接枚举消掉某一个点或者某两个点,复杂度O(n22n)O(n^22^n)O(n22n) 由于这个集合里面的所有点最终都会被消掉,因此顺序并不重要。 于是可以强制这一步会消掉lowbit(i)lowbit(i)lowbit(i) 那...

weixin_30776545的博客 125

c语言愤怒的小鸟,c/c++开发分享洛谷P2831 愤怒的小鸟(状压dp)

题意题目链接sol这题。。。。我样例没过就a了??。。算了,就当是样例卡精度吧。。直接状压dp一下,(f[sta])表示干掉(sta)这个集合里面的鸟的最小操作数转移的时候判断一下一次能干掉多少鸟。。#include #define ll long long using namespace std; const int maxn = 100001; inline int read() { ...

weixin_42362146的博客 673

洛谷P2831 愤怒的小鸟(状压dp)

P2831 愤怒的小鸟 题解 首先看数据,基本就是状压没跑了。 解法: 先预处理出所有可能的抛物线,对于每一个小猪猪,我们去看最多能连上几个小猪猪。将坐标带进去求解二元一次方程。如果a&amp;amp;amp;lt;0a&amp;amp;amp;lt;0a&amp;amp;lt;0,就去拓展最多能打几只小猪。 其次就是状态转移方程,考虑对于打掉iii只小猪最少需要的小鸟数量。我们用集合SSS代表已经打掉的小猪,equationequatione...

Eternally831143的博客 382
上一篇: 【题解】洛谷P2939 改造路(最短路 分层图)
下一篇: 【题解】洛谷P2324 骑士精神(A*算法 启发式搜索)
Rem_Inory
博客等级 码龄8年 4粉丝 140原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值