题目描述

Kiana最近沉迷于一款神奇的游戏无法自拔。

简单来说,这款游戏是在一个平面上进行的。

有一架弹弓位于(0,0)处,每次Kiana可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如y=ax2+bx的曲线,其中a,b是Kiana指定的参数,且必须满足a<0。

当小鸟落回地面(即x轴)时,它就会瞬间消失。

在游戏的某个关卡里,平面的第一象限中有n只绿色的小猪,其中第i只小猪所在的坐标为(xi,yi)。

如果某只小鸟的飞行轨迹经过了(xi,yi),那么第i只小猪就会被消灭掉,同时小鸟将会沿着原先的轨迹继续飞行;

如果一只小鸟的飞行轨迹没有经过(xi,yi),那么这只小鸟飞行的全过程就不会对第i只小猪产生任何影响。

例如,若两只小猪分别位于(1,3)和(3,3),Kiana可以选择发射一只飞行轨迹为y=-x2+4x的小鸟,这样两只小猪就会被这只小鸟一起消灭。

而这个游戏的目的,就是通过发射小鸟消灭所有的小猪。

这款神奇游戏的每个关卡对Kiana来说都很难,所以Kiana还输入了一些神秘的指令,使得自己能更轻松地完成这个游戏。这些指令将在【输入格式】中详述。

假设这款游戏一共有T个关卡,现在Kiana想知道,对于每一个关卡,至少需要发射多少只小鸟才能消灭所有的小猪。由于她不会算,所以希望由你告诉她。

输入

第一行包含一个正整数T,表示游戏的关卡总数。

下面依次输入这T个关卡的信息。每个关卡第一行包含两个非负整数n,m,分别表示该关卡中的小猪数量和Kiana输入的神秘指令类型。接下来的n行中,第i行包含两个正实数(xi,yi),表示第i只小猪坐标为(xi,yi)。数据保证同一个关卡中不存在两只坐标完全相同的小猪。

如果m=0,表示Kiana输入了一个没有任何作用的指令。
如果m=1,则这个关卡将会满足:至多用n/3+1只小鸟即可消灭所有小猪。
如果m=2,则这个关卡将会满足:一定存在一种最优解,其中有一只小鸟消灭了至少n/3只小猪。

保证1<=n<=18,0<=m<=2,0<xi,yi<10,输入中的实数均保留到小数点后两位。

输出

对每个关卡依次输出一行答案。

输出的每一行包含一个正整数,表示相应的关卡中,消灭所有小猪最少需要的小鸟数量

样例输入

2
2 0
1.00 3.00
3.00 3.00
5 2
1.00 5.00
2.00 8.00
3.00 9.00
4.00 8.00
5.00 5.00

样例输出

1 1


题解

状态压缩dp

这题也真是够坑。。。

考试时写了搜索,毕竟14年就没出搜索。然而出乎意料,这题竟然是16年的第二道dp,

还是考试前一直觉得不会考的一种dp。。。

f[i]表示状态为i的猪全部打掉需要的最少次数。

易推出伪代码f[i]=min(f[i],f[i^A]+1),A为每次打的集合。

为什么说是伪代码?因为A很难确定。

枚举子集的话,时间复杂度O(3^n),TLE。

所以不能枚举子集。

枚举点?先枚举情况,然后枚举两个点,再处理其余点,时间复杂度O(2^n*n^3),85分。

于是我们想到初始化。

本着能打则打的贪心原则,可以先把点j和点k所在抛物线上所有点存起来,状态转移时,

集合A即为i&g[j][k],省略了一重循环,AC。

当然还是有更好的优化(见代码)。

由于打的顺序对结果没有影响,所以可以默认先打标号较小的小鸟,这样时间复杂度会更低。

然而最坑的是精度问题。

不加精度肯定会跪,至于跪多少,考试时自己没加精度得了0分。。。

精度太低也不行,亲测1e-4 90分,1e-5 95分。

所以精度很重要,最好是1e-6,不会被卡,可以过。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define eps 1e-6
using namespace std;
double x[20] , y[20];
int f[262150] , g[20][20];
int main()
{int T;scanf("%d" , &T);while(T -- ){memset(g , 0 , sizeof(g));int n , m , i , j , k;double a , b;scanf("%d%d" , &n , &m);for(i = 0 ; i < n ; i ++ )scanf("%lf%lf" , &x[i] , &y[i]);for(i = 0 ; i < n ; i ++ ){for(j = 0 ; j < n ; j ++ ){if(i != j){a = (x[j] * y[i] - x[i] * y[j]) / (x[i] * x[j] * (x[i] - x[j]));b = (x[j] * x[j] * y[i] - x[i] * x[i] * y[j]) / (x[i] * x[j] * (x[j] - x[i]));if(a <= -eps)for(k = 0 ; k < n ; k ++ )if(fabs(a * x[k] * x[k] + b * x[k] - y[k]) <= eps)g[i][j] |= 1 << k;}}}f[0] = 0;for(i = 1 ; i < (1 << n) ; i ++ ){for(j = 0 ; j < n ; j ++ )if((1 << j) & i)break;f[i] = f[i ^ (1 << j)] + 1;for(k = 0 ; k < n ; k ++ )if(k != j && (1 << k) & i)f[i] = min(f[i] , f[i ^ (i & g[j][k])] + 1);}printf("%d\n" , f[(1 << n) - 1]);}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/6212798.html

[NOIP2016]愤怒的小鸟 状态压缩dp相关推荐

  1. 状态压缩DP AcWing算法提高课 (详解)

    基础课的状态压缩点这里 基础课中 蒙德里安的梦想 属于 棋盘式状态压缩dp,最短Hamilton路径 属于 集合状态压缩dp 1064. 小国王(棋盘式/基于连通性) 这种棋盘放置类问题,在没有事先知 ...

  2. 第一章 动态规划 状态压缩DP

    1.基本概述 状态压缩dp和状态机一样,都是一种特殊的状态表示方式.状态机用一系列小状态表示某一状态.状态压缩dp用二进制数进行表示.虽然看代码起来时间复杂度比较高,但是很多的情况都给剪枝掉了. 状态 ...

  3. 动态规划(5)状态压缩dp

    一.概述 动态规划的过程是随着阶段不断增长,在每个状态维度上不断扩展.在任意时刻,已经求出最优解的状态与尚未求出最优解的状态在各维度上的分界点组成了dp扩展的轮廓,对于某些问题,我们需要在动态规划的状 ...

  4. 0x56. 动态规划 - 状态压缩DP(习题详解 × 7)

    目录 Problem A. 最短Hamilton路径 ProblemB. 蒙德里安的梦想 Problem C. Corn Fields Problem D. 小国王 Problem E. 炮兵阵地 P ...

  5. POJ 2411 Mondriaan‘s Dream(最清楚好懂的状压DP讲解)(连通性状态压缩DP)

    poj 2411 Mondriaan's Dream(最清晰的状压DP解析) 闫氏DP大法好 我们这里是一列一列地来,因为是一个棋盘性的状态压缩DP,从哪个方向都一样 摆放的小方格总方案数 等价于 横 ...

  6. BZOJ1688|二进制枚举子集| 状态压缩DP

    Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) ...

  7. hdu1074 状态压缩dp+记录方案

    题意:       给你一些作业,每个作业有自己的结束时间和花费时间,如果超过结束时间完成,一天扣一分,问你把n个作业完成最少的扣分,要求输出方案. 思路:       状态压缩dp,记录方案数的地方 ...

  8. FZU-2218 Simple String Problem(状态压缩DP)

    原题地址: 题意: 给你一个串和两个整数n和k,n表示串的长度,k表示串只有前k个小写字母,问你两个不含相同元素的连续子串的长度的最大乘积. 思路: 状态压缩DP最多16位,第i位的状态表示第i位字母 ...

  9. 《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp

    文章目录 题目解答 题目链接 题目解答 分析: 状态压缩dp是用二进制数来表示状态. 数据范围n = 20, 那么状态总量就是2202^{20}220个状态. 可以按照以下思路去思考: 哪些点被用过 ...

最新文章

  1. mysql 触发器死循环_请教如何避免该条触发器的死循环
  2. Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)
  3. 【spider】selenium模拟点击斗鱼示例
  4. Java @SuppressWarnings注解
  5. iOS应用开发:什么是ARC?
  6. javaweb(09) EL表达式JSTL标签库(jsp相关,了解)
  7. IE成长之路--OSPF报文类型
  8. 《手机屏幕》参数与选择
  9. Android车牌识别SDK
  10. 海克斯棋开源程序 FutaHex2 编译教程
  11. linux python for循环语句,Python之for循环的使用
  12. Win10中文输入法加入美式英文键盘并默认英文键盘
  13. java web查询某个时间段记录
  14. 王学岗视频编码————视频编解码基础与MediaCodec编解码(对应1234节)
  15. 段码液晶显示屏液交期有多长?
  16. 今目标自动签退1.1版本
  17. Android 音频开发——AudioRecord录音
  18. 职场吐槽大会,原来办公软件也有如此多神技能?
  19. android版音乐播放器----卡拉OK歌词实现(二)
  20. [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐音效不求人,程序员也可以DIY

热门文章

  1. Java跳出多重循环
  2. 错误:unrecognized command line option “-std=c++11”
  3. h264 I帧的判断
  4. 第一章 处理器体系结构
  5. 前端学习(3101):vue+element今日头条管理-react简介2
  6. PS教程第八课:新建文件
  7. [jQuery] jQuery的attr和prop方法有什么区别?
  8. [css] 请用css写一个扫码的加载动画图
  9. [css] css中的baseline,你知道吗?
  10. [css] 如何将元素的所有css属性恢复为初始化状态?