P2831 愤怒的小鸟

传送门

看到数据范围就知道是搜索或状压DP

算了一波复杂度搜索好像过不了极限数据

搞状压

设 f [ i ] 表示所有猪的状态为 i (二进制下1表示死了,0表示没死)时需要的最少发射次数

设 p [ i ] [ j ] 存经过第 i 只猪和第 j 只猪的抛物线经过的猪的状态(可以$n^2$预处理出来,解方程都会吧..)

找到第一个没死的猪 i ,然后枚举所有其他没死的猪 j ,进行转移:

f [ i|p [ i ] [ j ] ] = min ( f [ i|p [ i ] [ j ] ],f [ i ] + 1 )

不用 n^2 枚举所有两只猪的 p [ i ] [ j ] ,因为第一头猪现在不死以后也要死,所以没有任何区别

当然还要考虑只经过一头猪的情况: f [ i|(1<<i-1) ] = min ( f[ i|(1<<i-1) ],f [ i ] +1 )

注意抛物线解析式中 a<0,记得判一下合法性

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) f=-1; ch=getchar(); }
    while(ch>=‘0‘&&ch<=‘9‘) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const double eps=1e-8;
const int N=300007;

int n,m,T;
struct data
{
    double x,y;
}d[27];
double a,b;
inline void slove(double x1,double y1,double x2,double y2)//解方程
{
    double t=x2*x2/x1/x1;
    b=(y2-y1*t)/(x2-x1*t); a=(y1-x1*b)/x1/x1;
}
int p[27][27];
int f[N];
void pre()
{
    memset(p,0,sizeof(p));
    memset(f,0x3f,sizeof(f)); f[0]=0;//记得初始化
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            if(fabs(d[i].x-d[j].x)<eps) continue;//如果横坐标相同则无解
            slove(d[i].x,d[i].y,d[j].x,d[j].y);
            if(a>=0) continue;//判断合法性
            for(int k=1;k<=n;k++) if(fabs(a*d[k].x*d[k].x+b*d[k].x-d[k].y)<=eps)/*如果抛物线经过猪k就记录一下*/ p[i][j]|=(1<<k-1);
        }
}
int main()
{
    T=read();
    while(T--)
    {
        n=read(); m=read();
        for(int i=1;i<=n;i++) scanf("%lf%lf",&d[i].x,&d[i].y);
        pre(); int mx=(1<<n)-1,pos;
        for(int i=0;i<=mx;i++)
        {
            for(int j=0;j<n;j++) if( !((i>>j)&1) ) { pos=j; break; }//找到第一只没死的猪
            f[i|(1<<pos)]=min(f[i|(1<<pos)],f[i]+1);//单独考虑
            for(int j=pos+1;j<n;j++)//与其他猪一起考虑
                if( !((i>>j)&1) ) f[i|p[pos+1][j+1]]=min(f[i|p[pos+1][j+1]],f[i]+1);//注意p的下标
        }
        printf("%d\n",f[mx]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/LLTYYC/p/9824696.html

时间: 2024-07-31 04:28:35

P2831 愤怒的小鸟的相关文章

P2831 愤怒的小鸟(状压dp)

P2831 愤怒的小鸟 我们先预处理出每个猪两两之间(设为$u,v$)和原点三点确定的抛物线(当两只猪横坐标相等时显然无解) 处理出$u,v$确定的抛物线一共可以经过多少点,记为$lines[u][v]$ 设$f[i]$表示已经被消灭的猪的集合为二进制表示为$i$时,需要的最小抛物线数 显然$f[0]=0$ $f[i|(1<<(u-1))]=min(f[i|(1<<(u-1)],f[i]+1)$(一条抛物线只串一个点) $f[i|lines[u][v]]=min(f[i|lines

P2831 愤怒的小鸟——状压

P2831 愤怒的小鸟 抛物线过原点,只要再找两个就能确定抛物线: 处理出两两之间的抛物线能过哪些点,状态压缩: 但是直接枚举每一条抛物线常数太大会T,所以我们需要预处理一个low_bit表示当前状态下第一个没选的,即是二进制下第一个不是1的位置: 因为我们早晚都要把它变成1,所以先处理他就可以达到要求: 注意精度问题: #include<cmath> #include<cstdio> #include<cstring> #include<algorithm>

【luogu P2831 愤怒的小鸟】 题解

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

【2019.10.18】luogu TG5动态规划进阶

树形dp P1352 没有上司的舞会 P2607 骑士(review) 对于每一个"联通快" 只有根节点有机会形成环 强制不选\(rt\)和\(rt\)的父亲 各跑一遍 P1131 时态同步(review) 贪心 显然增加深度约小的边越优 从下到上来调整 先将同一个点的儿子们延伸到一样 再往上进行一样的操作 //apio 烟火 树上背包? 一棵\(n\)个点的树,有点权.选择一个大小不超过\(K\)的联通块,使得点权和最大.\(n ≤ 2000\) \(f(x, i)\)表示\(x\)

题解 P2831 【愤怒的小鸟】

题目 我的天,这题是真的卡精度...... 主要是精度很不好处理,经本蒟蒻测验,精度在\(10^{-6}\)会比较好优雅 [分析] 对于这种某个变量特别小\((\leq 31)\)的题目,本蒟蒻第一反应就是状压 对于某个抛物线,一定要打到起码一个小猪(不然不如不要这一条抛物线) 有人觉得最少会打掉两只小猪的,可以仔细想一下,万一\(a \geq 0\)呢...... 好的,我们继续 那么,我们可以这么考虑,枚举每一只小猪的坐标 首先,有一条抛物线是只过它的 其次,再枚举其他小猪,算出抛物线方程(

【NOIP2016】愤怒的小鸟

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

茁足生活就像愤怒的小鸟,当你摔倒时,总有几只绿猪在笑你.

阻滋诅资纵淄抓注撞 生活就像愤怒的小鸟,当你摔倒时,总有几只绿猪在笑你 http://passport.baidu.com/?business&un=vip&un=%5F%E7%BD%97%E7%94%B8%E6%8C%89%E6%91%A9%E7%BE%8E%E5%A5%B3%5F#0 http://passport.baidu.com/?business&un=vip&un=%5F%E8%8D%94%E6%B3%A2%E6%8C%89%E6%91%A9%E7%BE%8E

[NOIP2016]愤怒的小鸟 D2 T3 状压DP

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

看--愤怒的小鸟

宣称是Sony大作实为Rovio Mobile的电影作品,愤怒的小鸟本身就是游戏出身,这貌似是他的第一次电影化,我以前做手游解说的时候玩过几百个手游,他们家的作品自然是很出色的,多次推荐,好玩的地方在于:1 形象设计 2 关卡设计 3 参数多样化与混合 ,在这之前他们其实还出过动画片,基本无配音,形象完全无改变(鸟跟猪都没有四肢,因为在弹弓游戏里面不需要),甚至弹弓都不变,两大阵营不是鸟就是猪,把游戏中短小的背景做成动画的作品,一集两分钟,不清楚他们制作的意图但跟电影制作应该关系不大.##开始前