UOJ265 NOIP2016D2T3 愤怒的小鸟 状态压缩DP
来源:互联网 发布:光猫 lan端口绑定 编辑:程序博客网 时间:2024/05/22 10:46
大家都很强,可与之共勉 。
秒题系列
描述
Kiana 最近沉迷于一款神奇的游戏无法自拔。
简单来说,这款游戏是在一个平面上进行的。
有一架弹弓位于 (0,0)(0,0) 处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如 y=ax2+bxy=ax2+bx 的曲线,其中 a,ba,b 是 Kiana 指定的参数,且必须满足 a<0a<0,a,ba,b 都是实数。
当小鸟落回地面(即 xx 轴)时,它就会瞬间消失。
在游戏的某个关卡里,平面的第一象限中有 nn 只绿色的小猪,其中第 ii 只小猪所在的坐标为 (xi,yi)(xi,yi)。
如果某只小鸟的飞行轨迹经过了 (xi,yi)(xi,yi),那么第 ii 只小猪就会被消灭掉,同时小鸟将会沿着原先的轨迹继续飞行;
如果一只小鸟的飞行轨迹没有经过 (xi,yi)(xi,yi),那么这只小鸟飞行的全过程就不会对第 ii 只小猪产生任何影响。
例如,若两只小猪分别位于 (1,3)(1,3) 和 (3,3)(3,3),Kiana 可以选择发射一只飞行轨迹为 y=−x2+4xy=−x2+4x 的小鸟,这样两只小猪就会被这只小鸟一起消灭。
而这个游戏的目的,就是通过发射小鸟消灭所有的小猪。
这款神奇游戏的每个关卡对 Kiana 来说都很难,所以 Kiana 还输入了一些神秘的指令,使得自己能更轻松地完成这个游戏。这些指令将在【输入格式】中详述。
假设这款游戏一共有 TT 个关卡,现在 Kiana 想知道,对于每一个关卡,至少需要发射多少只小鸟才能消灭所有的小猪。由于她不会算,所以希望由你告诉她。
输入
从标准输入读入数据。
第一行包含一个正整数 TT,表示游戏的关卡总数。
下面依次输入这 TT 个关卡的信息。每个关卡第一行包含两个非负整数 n,mn,m,分别表示该关卡中的小猪数量和 Kiana 输入的神秘指令类型。接下来的 nn 行中,第 ii 行包含两个正实数 xi,yixi,yi,表示第 ii 只小猪坐标为 (xi,yi)(xi,yi)。数据保证同一个关卡中不存在两只坐标完全相同的小猪。
如果 m=0m=0,表示 Kiana 输入了一个没有任何作用的指令。
如果 m=1m=1,则这个关卡将会满足:至多用 ⌈n/3+1⌉⌈n/3+1⌉ 只小鸟即可消灭所有小猪。
如果 m=2m=2,则这个关卡将会满足:一定存在一种最优解,其中有一只小鸟消灭了至少 ⌊n/3⌋⌊n/3⌋ 只小猪。
保证 1≤n≤181≤n≤18,0≤m≤20≤m≤2,0
输出
输出到标准输出。
对每个关卡依次输出一行答案。
输出的每一行包含一个正整数,表示相应的关卡中,消灭所有小猪最少需要的小鸟数量。
开始eps取大了(1e-8),就在Extra Test挂了,eps改为1e-10就好
预处理出两只猪组成的抛物线可以覆盖哪些猪, 用一个数来存233。
然后转移就看代码…..
# include <bits/stdc++.h>const double eps = 1e-10 ;const int N = 1 << 18 | 1 ;inline void smin ( int& d, const int& x ) { ( d > x ) ? ( d = x ) : 0 ; }int dp [N] ;int g [20] [20] ;std :: pair < double, double > bird [20] ;int main ( ) { int T ; for ( scanf ( "%d", & T ) ; T ; -- T ) { int n, m ; scanf ( "%d%d", & n, & m ) ; for ( int i = 1 ; i <= n ; ++ i ) { scanf ( "%lf%lf", & bird [i].first, & bird [i].second ) ; } for ( int i = 1 ; i <= n ; ++ i ) for ( int j = i + 1 ; j <= n ; ++ j ) { g [i] [j] = 0 ; if ( fabs ( bird [i].first - bird [j].first ) < eps ) continue ; double a, b ; b = ( bird [i].second / ( bird [i].first * bird [i].first ) - bird [j].second / ( bird [j].first * bird [j].first ) ) / ( 1 / bird [i].first - 1 / bird [j].first ) ; if ( ( a = ( bird [i].second - b * bird [i].first ) / ( bird [i].first * bird [i].first ) ) < -eps ) for ( int k = 1 ; k <= n ; ++ k ) if ( fabs ( a * bird [k].first * bird [k].first + b * bird [k].first - bird [k].second ) < eps ) g [i] [j] |= ( 1 << ( k - 1 ) ) ; } int lim = ( 1 << n ) ; for ( int s = 1 ; s < lim ; ++ s ) dp [s] = 1e18 ; dp [0] = 0 ; for ( int s = 0 ; s < lim ; ++ s ) { if ( dp [s] == 1e18 ) continue ; for ( int i = 1 ; i <= n ; ++ i ) { for ( int j = i + 1 ; j <= n ; ++ j ) { smin ( dp [s | g [i] [j]], dp [s] + 1 ) ; } smin ( dp [s | ( 1 << ( i - 1 ) )], dp [s] + 1 ) ; } } printf ( "%d\n", dp [( 1 << n ) - 1] ) ; }}
改进
会发现时间跑得很慢…..
我们发现会出现重复转移的情况。
我们可以这样避免。
for ( int s = 0 ; s < lim ; ++ s ) { if ( dp [s] == 1e8 ) continue ; for ( int i = 1 ; i <= n ; ++ i ) { if ( !( s & ( 1 << ( i - 1 ) ) ) ) { for ( int j = i + 1 ; j <= n ; ++ j ) { smin ( dp [s | g [i] [j]], dp [s] + 1 ) ; } smin ( dp [s | ( 1 << ( i - 1 ) )], dp [s] + 1 ) ; break ; } } }
- UOJ265 NOIP2016D2T3 愤怒的小鸟 状态压缩DP
- Luogu2831/UOJ265[NOIP2016D2T3] 愤怒的小鸟【状压DP】
- [状压DP]【NOIP2016D2T3】愤怒的小鸟 题解
- NOIP2016D2T3 愤怒的小鸟
- uoj265【2016提高】愤怒的小鸟(状压dp)
- UOJ265 NOIP2016 day2 T3 愤怒的小鸟(状压DP+预处理)
- 【jzoj4908】【NOIP2016提高组】【愤怒的小鸟】【状态压缩动态规划】
- [NOIP] [状压DP] NOIP2016Day2 愤怒的小鸟
- 愤怒的小鸟(状压DP)
- [NOIP2016][状压DP]愤怒的小鸟
- NOIP2016 愤怒的小鸟 [状压DP]
- Noip2016 愤怒的小鸟 【状压DP】
- NOIP2016 愤怒的小鸟 (状压DP)
- NOIP2016 [愤怒的小鸟] 状压DP
- 【状压DP】NOIP2016Day2T3[愤怒的小鸟]题解
- 愤怒的小鸟
- 愤怒的小鸟
- 愤怒的小鸟
- 【小波分析】学习笔记(二):傅里叶变换和短期傅里叶变换
- spring boot+mybatis+通用mapper+pageHelper+druid的多数据源(非读写分离)
- MySQL中的数据类型详解
- 【python】configparser读写配置文件
- Spring RedisTemplate操作-HyperLogLog操作
- UOJ265 NOIP2016D2T3 愤怒的小鸟 状态压缩DP
- socken.io文档
- Spring RedisTemplate操作-序列化操作
- vuzzer测试示例-base64
- 加载头布局
- Training set,Gallery set,Probe sets
- qt关于程序崩溃
- leetcode 173. Binary Search Tree Iterator 二叉树中序遍历非递归
- WIN7下安装运行mongodb