[NOIP2016 提高组] 愤怒的小鸟

[NOIP2016 提高组] 愤怒的小鸟

题意:

有n只猪,给出猪的坐标(xi,yi),问最少用几个形如 y=ax^2+bx 的曲线可以保证所有猪在曲线上,满足a<0,a,b为实数
n<=18,

题解:

两个方法:爆搜或者状压dp

状压dp

看n<=18也就能看出来,这数据范围就是用状压dp
我们用二进制来表示哪些猪已经被曲线标记,比如11(十进制),二进制下是000001011,表示第1,2,4头猪已经被标记
首先对于每个状态,我们用state[i]记录其第一次0出现的位置(从右往左),这将作为我们dp的起点

for(int i=0;i<(1<<18);i++){int j=1;for(;j<=18 && i&(1<<(j-1));j++);start[i]=j;//记录该状态下,出现第一个0的位置 }

然后我们枚举两个点带入到式子y=ax^2+bx,求出a和b,a必须大于0,然后枚举所有点,看哪些点在这个抛物线上,用line[i][j]来记录能经过哪些猪🐖
然后对于每一种状态,起点就是我们之前求的0的第一次位置,然后枚举其他点x,x有可能在抛物线上,也有可能单独成抛物线,取最小
详细看代码

爆搜

参考题解
对于每个猪,如果他不能存在于之前的抛物线,就与其他猪构成抛物线,然后继续搜。还有一种选择:暂时不与其它猪组成抛物线
代码里有大量详细的注释

代码:

状压dp

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int T,n,m,lines[19][19],start[1<<19],dp[1<<19];
double x[19],y[19];
void equation(double &a,double &b,int i,int j){a=-(y[i]*x[j]-y[j]*x[i])/(x[j]*x[j]*x[i]-x[i]*x[i]*x[j]);b=(y[i]*x[j]*x[j]-y[j]*x[i]*x[i])/(x[i]*x[j]*x[j]-x[j]*x[i]*x[i]);
}
int main(){for(int i=0;i<(1<<18);i++){int j=1;for(;j<=18 && i&(1<<(j-1));j++);start[i]=j;//记录该状态下,出现第一个0的位置 }scanf("%d",&T);for(int i=1;i<=T;i++){memset(lines,0,sizeof(lines));memset(dp,1,sizeof(dp));dp[0]=0;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(fabs(x[i]-x[j])<eps) continue;//横坐标相等 double a,b;equation(a,b,i,j);if(a>-eps) continue;//必须开口向下 for(int k=1;k<=n;k++)//枚举被抛物线经过的点 if(fabs(a*x[k]*x[k]+b*x[k]-y[k])<eps)lines[i][j]|=(1<<(k-1));}for(int i=0;i<(1<<n);i++){int j=start[i];dp[i|(1<<(j-1))]=min(dp[i|(1<<(j-1))],dp[i]+1); for(int k=1;k<=n;k++)dp[i|lines[j][k]]=min(dp[i|lines[j][k]],dp[i]+1); }printf("%d\n",dp[(1<<n)-1]);}return 0;
}

爆搜代码:

/*思路:搜索。
对于第i只猪,如果它已经被前面所构造的某条抛物线经过了,
就不用处理了,继续往下搜索。否则,就有两种选择,第一种
是与前面某一只单独的猪(即这只猪未与其它猪组成抛物线)
组成抛物线,因为两只猪最多也只能被一条抛物线相连;第二
种是暂时不与其它单独的猪组成抛物线。最后,将抛物线的条
数与余下的猪的个数相加(因为单独的一只猪也要一条抛物线
将其击中)就是搜索出来的一个合法的结果。*/ 
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<string>
#include<sstream>
#include<cstring>
#include<cmath>using namespace std;const double eps=1e-8;
/*因为浮点数的精度计算太过复杂,像3.14这样的数存在浮
点型变量里存的可能是3.139999999,也有可能是3.140000001,
所以不能直接用“==”判断两个浮点数是否相等。在这种情况
下,就允许判断两个浮点数为相等时,两数之间存在微小的误差,
这个“微小的误差”要取一个较小的数,比如1e-8,这样就不
会判不出也不会误判了。*/
bool dy(double a,double b)//判断两个浮点数是否相等的函数 
{//如果a和b之间相差的值小于eps(即1e-8),就说明它们是相等的 return fabs(a-b)<eps;//fabs用于取浮点数的绝对值 
}int n=0,m=0,ans=0;//x数组存每只猪的x坐标,y数组存每只猪的y坐标//pwxa数组存每条已构造的抛物线的参数a,pwxb数组存每条已构造的抛物线的参数b//tx数组存每只单独的猪的x坐标,ty数组存每只单独的猪的y坐标 double x[20],y[20],pwxa[20],pwxb[20],tx[20],ty[20];
//dfs(c,u,v)表示当前搜到第c只猪,已构造抛物线的数量为u,单独的猪的数量为v时的情况 
//注意:当前抛物线的总数量为(u+v)条,因为除已有的抛物线外,每一只单独的猪也需要一条抛物线来击中它 
void dfs(int c,int u,int v)
{//最优性剪枝,因为即使后面的每一只猪都被当前已构造的抛物线击中, //或者与其它单独的猪组成抛物线,抛物线的总数量还是(u+v),不会减少,//所以如果抛物线的总数量已经大于等于当前的最优解时,搜下去也不会//比当前更优了,就不用继续搜下去了。if(u+v>=ans) return;if(c>n)//如果搜完了 {ans=u+v;//记录答案,因为前面已经有最优性剪枝了,所以没被剪掉的答案一定比当前更优 return;//结束 }bool flag=false;//记录是否被已构造的抛物线经过 for(int i=1;i<=u;i++)//枚举已构造的抛物线 //将这一条抛物线的参数与当前猪的x坐标带进函数解析式算一遍,//如果结果等于当前猪的y坐标,就说明当前猪已经被已构造的抛物线经过了 if(dy(pwxa[i]*x[c]*x[c]+pwxb[i]*x[c],y[c])){dfs(c+1,u,v);//被经过了就直接往下搜 flag=true;//记录 break;//退出循环,既然当前猪已经被经过了,再继续判断也没有意义了}if(!flag)//如果没有被经过 {for(int i=1;i<=v;i++)//枚举单独的猪 {//如果当前猪与这一只单独的猪的x坐标相同,就说明它们不能组成一条//抛物线。因为若想使它们组成一条抛物线,弹弓的位置就必须是它们的正下//方,然后往上垂直发射,但是弹弓的位置固定在(0,0),而猪的x坐标又大于//0(题目数据范围),所以它们不能组成一条抛物线。如果不加这个判//断的话就会计算出一些奇奇怪怪的东西,影响后面的判断,所以还是加上为好。 if(dy(x[c],tx[i])) continue;//如果当前猪与这一只单独的猪的x坐标相同,跳过这一次循环//求参数a、b的过程实际上就是解一个二元一次方程组,比如说有两只猪的坐标分别是(1,3)和(3,3), //现在要求出它们所组成的抛物线的参数a与参数b。将两只猪的坐标分别代入到函数解析式中,//就可以得出一个方程组: 3=a+b  3=9a+3b 。这是,我们可以用加减消元法消掉b,将两个方程//分别乘上另一个方程的b的系数,得:9=3a+3b 3=9a+3b。这样,两个方程中的b的系数就一致了,//然后直接用一个式子减去另一个式子,再将a的系数化为一即可。最后再将a带入到回任意一个方程求b即可。//因为这里的所有方程都长一个样,所以这一种方法是通用的。 double a=(y[c]*tx[i]-ty[i]*x[c])/(x[c]*x[c]*tx[i]-tx[i]*tx[i]*x[c]);//求参数a double b=(y[c]-x[c]*x[c]*a)/x[c];//将a代入求参数b if(a<0)//如果这一个解是合法的,就说明当前猪与这一只单独的猪可以组成抛物线 {   pwxa[u+1]=a;//记录抛物线的参数a pwxb[u+1]=b;//记录抛物线的参数b//将这一只单独的猪从数组中删去,因为它已经和当前猪组成抛物线,不再单独了 double q=tx[i],w=ty[i];for(int j=i;j<v;j++){tx[j]=tx[j+1];ty[j]=ty[j+1];}dfs(c+1,u+1,v-1);//继续往下搜//将这一只单独的猪放回数组(回溯) for(int j=v;j>i;j--) {tx[j]=tx[j-1];ty[j]=ty[j-1];}tx[i]=q;ty[i]=w;}}//还有一种选择:暂时不与其它猪组成抛物线 tx[v+1]=x[c];ty[v+1]=y[c];dfs(c+1,u,v+1);//继续往下搜 }
}
int main()
{int T=0;scanf("%d",&T);for(int Q=1;Q<=T;Q++){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%lf%lf",&x[i],&y[i]);ans=100;//记得初始化 dfs(1,0,0);//搜 printf("%d\n",ans); } return 0;//完美地结束 
}
//借鉴大神之作
//完美爆搜

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P5208-[WC2019] I 君的商店【交互,二分】

正题 题目链接:https://www.luogu.com.cn/problem/P5208 题目大意 有一个长度为nnn的010101序列aaa&#xff0c;你知道里面有奇数个111还是偶数个111。你每次可以选择两个下标集合S/TS/TS/T询问集合SSS和集合TTT位置的数字和哪个更大。 交互库只会告诉你S≤TS\leq TS≤T或者…

模板:后缀数组(SA)

文章目录前言解析后缀排序优化1&#xff1a;基数排序优化2&#xff1a;简化第一次排序优化3&#xff1a;提前break完整代码LCP与height所谓后缀数组&#xff0c;就是存储后缀的数组 &#xff08;逃&#xff09; 前言 为什么一个算法&#xff0c;如此难以理解却依然是成为一个…

P3959 [NOIP2017 提高组] 宝藏

P3959 [NOIP2017 提高组] 宝藏 题意: 额题意不好说&#xff0c;就是n个点m个边&#xff0c;选定一个点为根节点&#xff0c;构造一个最小生成树&#xff0c;边的权值为该该边起点到根节点之间的点的数量K&#xff08;不含根节点&#xff09; * 道路长度 1<n<12 0<m&…

如何在ASP.NET Core程序启动时运行异步任务(3)

原文&#xff1a;Running async tasks on app startup in ASP.NET Core (Part 3)作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu之前我写了两篇有关在ASP.NET Core中运行异步任务的博文&#xff0c;本篇博文是对之前两篇博文中演示示例和实现方法的简短跟进。你可以通过…

CF1140G-Double Tree【最短路,矩阵乘法,树上倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF1140G 题目大意 给出一个nnn个点的树TTT&#xff0c;然后复制一份T′TT′&#xff0c;每个TTT中的点iii向T′TT′中的点iii都有连边构成一张图。 图上所有权值各不相同&#xff0c;现在qqq次询问图上两点的最短路。 1≤n≤…

数论六之计算几何——An Easy Problem,Ancient Berland Circus,Open-air shopping malls

可检验模板正确度An Easy Problem?!Ancient Berland CircusOpen-air shopping mallsAn Easy Problem?! problem 就是大讨论 #include <cmath> #include <cstdio> #include <iostream> using namespace std; #define eps 1e-6struct vec {double x, y;ve…

CodeForces:12271261(div1)1262(div2)

文章目录前言CF1227A Math ProblemDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227B BoxDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227C MessyDescription\text{Des…

【NET CORE微服务一条龙应用】应用部署

简介本章主要介绍https://github.com/q315523275/FamilyBucket上微服务一条龙应用&#xff0c;在实际使用中的应用部署&#xff0c;以原始方式部署非docker部署应用主要包括&#xff1a;1、网关应用部署2、授权认证应用部署3、配置中心查询服务端应用部署4、综合管理应用部署5、…

牛客网区间dp练习

NC13230 合并回文子串 NC16129 小小粉刷匠 NC19909 [CQOI2007]涂色PAINT NC19997 [HAOI2016]字符合并 NC20238 [SCOI2003]字符串折叠 NC20252 [SCOI2007]压缩 NC20312 [SDOI2008]SUE的小球 POJ3042 Grazing on the Run

CF516D-Drazil and Morning Exercise【树上差分,倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF516D 题目大意 给出一棵nnn个点的树&#xff0c;定义f(x)f(x)f(x)表示距离点xxx最远的点的距离&#xff0c;qqq次询问给出一个kkk&#xff0c;要求一个最大的连通块满足连通块中所有点的f(x)f(x)f(x)最大最小差值不能超过k…

容斥问卷调查反馈——Co-prime,Character Encoding,Tree and Constraints,「2017 山东一轮集训 Day7」逆序对

文章目录Co-primesourcesolutioncodeCharacter EncodingsourcesolutioncodeTree and Constraintssourcesolutioncode「2017 山东一轮集训 Day7」逆序对sourcesolutioncodeCo-prime source TTT组数据&#xff0c;给出&#x1d43f;,&#x1d445;,&#x1d441;&#x1d43f;, …

手工修复Azure DevOps无法连接到Azure的问题

点击上方蓝字关注“汪宇杰博客”今天我在为一个从TFVC迁移到Git的老项目重新配置发布到Azure App Service的CI/CD管线的时候&#xff0c;Azure DevOps竟然爆了。这是一个微软已知的bug&#xff0c;目前还未修复&#xff0c;我来带大家看看如何手工workaround这个问题。首先&…

Loj#576-「LibreOJ NOI Round #2」签到游戏【线段树】

正题 题目链接:https://loj.ac/p/576 题目大意 给出一个长度为nnn的序列aaa&#xff0c;还有一个未知序列bbb&#xff0c;你每次可以花费gcd⁡ilrai\gcd_{il}^r a_igcdilr​ai​的代价得到∑ilrbi\sum_{il}^rb_i∑ilr​bi​的值。 每次修改aaa中的一个数&#xff0c;求得到b…

NC14732 锁

NC14732 锁 题意&#xff1a; n个居民&#xff0c;门上有k把锁&#xff0c;每个居民有若干钥匙&#xff0c;为1到k的一个子集&#xff0c;如果几名居民的钥匙的并集是1到k&#xff0c;即他们拥有全部锁的对应钥匙。 求最小的k&#xff0c;使得可以适当地给居民们每人若干钥匙…

CodeForces:1103(div1)1104(div2)

文章目录前言CF1104A Splitting into digitsDescription\text{Description}DescriptionSolution\text{Solution}SolutionDescription\text{Description}DescriptionCF1104B Game with stringDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text…

专题突破一之分块——Untitled Problem II,Balanced Lineup,[ioi2009]Regions

文章目录SP2940 UNTITLE1 - Untitled Problem IIsourcesolutioncodeBalanced LineupsourcecodeCount on a tree II[ioi2009]RegionsSP2940 UNTITLE1 - Untitled Problem II source solution 分块 si{sik(i−l1)sikik(1−l)l≤i≤rsik(r−l1)r<is_i\begin{cases} s_ik\tim…

.NET Core实战项目之CMS 第十七章 CMS网站系统的部署

目前我们的.NET Core实战项目之CMS系列教程基本走到尾声了&#xff0c;通过这一系列的学习你应该能够轻松应对.NET Core的日常开发了&#xff01;当然这个CMS系统的一些逻辑处理还需要优化&#xff0c;如没有引入日志组件以及缓存功能&#xff0c;权限目前只支持控制到菜单&…

ICPC2019南昌区域赛

ICPC2019南昌区域赛 题号题目知识点难度A9102BA Funny Bipartite Graph状压dp思维稳银快金CAnd and Pair二项式定理快铜DBitwise TreeEBob’s Problem思维&#xff0c;生成树签到FDynamic Suffix ArrayGEating Plan思维题稳铜快银HPowers of TwoIResistanceJSummonKTreeLWho i…

Loj#510-「LibreOJ NOI Round #1」北校门外的回忆【线段树】

正题 题目链接:https://loj.ac/p/510 题目大意 给出一个代码 function add(x,v)while x < n dos[x] s[x] xor vx x lowbit(x) //注意&#xff0c;这里是 lowbit&#xff0c;这也是两份代码唯一的区别end while end functionfunction query(x)ans 0while x > 0 doa…

如何用EFCore Lazy Loading实现Entity Split

α角 与 β角支持 现实生活 的 计算机系统&#xff0c;总有着两大偏差&#xff0c;第一个是 现实生活 与 计算机系统 的α角&#xff0c;另外一个是计算机系统的 逻辑设计 与 物理设计 的β角。举个栗子&#xff1a;α角&#xff1a;假设某个公司的商业流程&#xff0c;我们在做…