[NOIp 2016]愤怒的小鸟

Description

Input

Output

Sample Input

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

Sample Output

1
1

Sample Explanation

HINT

题解

暴力做法:

1、因为三点可以确定一条抛物线,又必过原点,那么只需要再找两个点就能确定一条抛物线;

2、枚举点对,求出抛物线方程,注意两点的$x$坐标不能相等,抛物线的二次项系数必须小于$0$;

3、删掉在抛物线上的点,进入下一层继续枚举。

60分算法:

1、如果使用暴力,我们会删掉一些线段进入下一个状态,一个状态是指现在平面内还剩多少个点;

2、注意到一点:从当前状态无论以什么方式删点,均不会影响之前状态到当前状态的决策。也就是说:在之前的状态时,我们只需要考虑,怎样删点来到达当前状态即可,而不用管当前状态下如何删点来到达下一个状态;

3、这具备明显的无后效性,我们用一个二进制数$S$来表示一个状态,若$S$的第$i$位为$1$,则表示第$(i+1)$个点还存在于平面内,那么状态压缩的$DP$可以解决;

4、同样对于每个状态枚举抛物线即可。

100分算法:

1、平面内有$n$个点,共$2^n$个状态,每次枚举抛物线还要检查每个点,需要$O(n^3)$复杂度;

2、每次都要枚举抛物线经过的两个点,即抛物线必定会删去的两个点。既然我们的最终目标是将当前状态所有的点都删去,那么可以知道,删掉所有点的最优方案中,一定会有一条抛物线经过当前状态的第一个点(否则就没法删掉它了);

3、那么我们只需要枚举经过当前状态第一个点的抛物线就可以(这么做一定不会有错误的决策)。

 1 #include <set>
 2 #include <map>
 3 #include <ctime>
 4 #include <cmath>
 5 #include <queue>
 6 #include <stack>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <string>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 #define x1 x[i]
15 #define x2 x[j]
16 #define y1 y[i]
17 #define y2 y[j]
18 #define LL long long
19 #define Max(a, b) ((a) > (b) ? (a) : (b))
20 #define Min(a, b) ((a) < (b) ? (a) : (b))
21 using namespace std;
22 const double ex=1e-8;
23 int st[20] = {1};
24
25 int n, m;
26 double x[20], y[20];
27 int c[20][20];
28 int f[(1<<18)+5];
29
30 void work(){
31     scanf("%d%d", &n, &m);
32     for (int i = 0; i < n; i++)
33     scanf("%lf%lf", &x[i], &y[i]);
34     memset(c, 0, sizeof(c));
35     for (int i = 0; i < n; i++)
36     for (int j = i+1; j < n; j++){
37         double a = (x1*y2-y1*x2)/(x1*x2*x2-x1*x1*x2);
38         if (a >= 0) continue;
39         double b = (y1-a*x1*x1)/x1;
40         for (int k = 0; k < n; k++)
41         if (abs(y[k]-a*x[k]*x[k]-b*x[k]) <= ex)
42             c[i][j]+=st[k];
43     }
44     memset(f, 127, sizeof(f));
45     f[0]=0;
46     int lim = (1<<n)-1;
47     int INF = f[1];
48     for (int i = 0; i <= lim; i++)
49     if (f[i] != INF)
50         for (int j = 0; j < n; j++)
51         if (!(i&st[j])){
52             f[i|st[j]] = Min(f[i|st[j]], f[i]+1);
53             for (int k = j+1; k < n; k++){
54             int tmp = i|c[j][k];
55             f[tmp] = Min(f[tmp], f[i]+1);
56             }
57         }
58     printf("%d\n", f[lim]);
59 }
60
61 int main(){
62     for (int i = 1; i <= 18; i++)
63     st[i] = st[i-1]<<1;
64     int t;
65     scanf("%d", &t);
66     while (t--)
67       work();
68     return 0;
69 }
时间: 2024-10-13 22:19:27

[NOIp 2016]愤怒的小鸟的相关文章

NOIP 2016 迟来的满贯

17-03-22,雨 17-03-22,一个特别重要的日子 在这一天,本蒻攻克了NOIP 2016最难的一题,D1T2--天天爱跑步 实现了NOIP 2016的AK! YAYAYAYAYAYAY 自然遭到了众巨神的膜拜--他们不屑于做这种弱菜才做的题目--RP又掉了 17-03-22于福州

noip 2016 天天爱跑步

描述 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一棵包含n个结点和n - 1条边的树,每条边连接两个结点,且任意两个结点存在一条路径互相可达.树上结点编号为从1到n的连续正整数. 现在有m个玩家,第i个玩家的起点为Si,终点为Ti.每天打卡任务开始时,所有玩家 在第0秒 同时从 自己的起点 出发,以 每秒跑一条边 的速度,不间断地沿着最短路径向着 自己的终点 跑去,

NOIp 2016 总结

NOIp 2016 总结 -----YJSheep Day 0 对于考前的前一天,晚自习在复习图论的最短路和生成树,加深了图的理解.睡得比较早,养足精力明日再战. Day 1 拿到题目,先过一边,题目都很长,心中有些忐忑. T1是一道模拟,关键是对位置进行操作,题目比较水,,但我好像没处理好当取模为0的情况,因为0与等价,但输出的时候有特殊处理,估计会wa几个点.太不应该了. T2是一道图论的题目,还好昨晚复习了,有点基础.要想做出来显然不可能,我选择用深搜来遍历每条路,估计不是爆栈就是超时,但

模拟(玩具谜题NOIP 2016 提高组 Day 1 第一题vijos2003)

描述 小南有一套可爱的玩具小人,它们各有不同的职业. 有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉小南一个谜题:“眼镜藏在我左数第3个玩具小人的右数第1个玩 具小人的左数第2个玩具小人那里.” 小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向:而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向. 小

【NOIP】提高组2016 愤怒的小鸟

[题意]Universal Online Judge [算法]状态压缩型DP [题解]看数据范围大概能猜到是状压了. 根据三点确定一条抛物线,枚举两个点之间的抛物线,再枚举有多少点在抛物线上(压缩为状态c[]),这样预处理出至多n*n/2+n条抛物线.(注意加上只经过一点的抛物线) 然后f[i]表示猪的消灭状态为i的最小步数,转移方程:f[i&c[j]]=min(f[i&c[j]],f[i]+1). #include<cstdio> #include<cstring>

Noip 2016 Day 1 &amp; Day 2

Day 1 >>> T1 >> 水题直接模拟AC: 考察三个知识点:1.你能不能编程 2.你会不会取模 3.你脑子抽不抽 然而第一次评测还是90,因为当模运算时 " end == 0 " 时需要将 end 改成 n: 代码: 1 #include <bits/stdc++.h> 2 3 const int N = 1e5 + 5 ; 4 5 int n , k , x , y , end ; 6 7 struct node { 8 int id

noip 2016 提高组试题看法

前几天写的那个纯属搞笑.(额,好吧,其实这个也不怎么正经) 就先说说day2吧: T1:这个东西应该叫做数论吧. 然而我一看到就照着样例在纸上推了大半天(然而还是没有看出来这东西是个杨辉三角) 然后就想干脆先把n≤25的拿了再说(这个爆不了long long) 然后就硬套用那个组合数公式. 再然后,就只拿了35分. T2:我勒个去. 这个东西应该用堆来优化的吧. 然而并不会堆. 然后就切一个遍历一遍把两端都再加进去(虽然我知道这个时间复杂度估计连20都拿不了). 一个估计是正解的东西: 思考一下

Noip 2016 Day1 题解

老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+25+24 实际分数:100+25+12 T1:玩具谜题 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉小南一个谜題: “眼镜藏在我左数第3个玩具小

【noip 2016】提高组

D1T1.玩具谜题 题目链接 直接模拟就好了--water.(然而比赛的时候数组开少了一个0) 1 #include<cstdio> 2 int n,m,a,s,ans; 3 struct node{char name[12];int dir;}x[100050]; 4 int main() 5 { 6 scanf("%d%d",&n,&m); 7 for(int i=0;i<n;i++)scanf("%d%s",&x[i]