题目:https://www.luogu.org/problemnew/show/P2831

一开始想 n^3 贪心来着;

先按 x 排个序,那么第一个不就一定要打了么?

在枚举后面某一个,和它形成一条抛物线,选能顺便打掉最多的那个;

然后连样例都过不了...

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-9
using namespace std;
int T,n,m,ans;
bool vis[];
struct N{
double x,y;
}p[];
bool cmp(N x,N y){return x.x<y.x;}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(vis,,sizeof vis);
ans=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+,p+n+,cmp);
for(int i=;i<=n;i++)
{
if(vis[i])continue; vis[i]=;
// printf("i=%d\n",i);
double x1=p[i].x, y1=p[i].y, xx=x1*x1, x2,y2,xy,a,b,aa=,bb=;
for(int j=i+;j<=n;j++)
{
int cnt=,mx=;
if(vis[j]||p[j].x==p[i].x)continue;
x2=p[j].x; y2=p[j].y; xy=x2*x2;
// y2=y2/x2*x1; xy=xy/x2*x1;
// a=(y1-y2)/(xx-xy);
a=(y1*x2-y2*x1)/(x1*x2*(x1-x2));
b=(y1-a*xx)/x1;
// printf("%lf %lf\n",a,b);
for(int k=j+;k<=n;k++)
{
if(vis[k])continue;
double tx=p[k].x,ty=p[k].y;
if(a*tx*tx+b*tx-ty<eps)cnt++;
}
if(cnt>mx)mx=cnt,aa=a,bb=b;
}
if(aa||bb)
for(int j=i+;j<=n;j++)
if(fabs(aa*p[j].x*p[j].x+bb*p[j].x-p[j].y)<eps)vis[j]=;
ans++;
}
printf("%d\n",ans);
}
return ;
}

仔细想想,贪心可能是错的;

正解是状压DP,DP真是与贪心相对的正确解法啊...

n 很小,所以想到状压,记录所有可能的抛物线的打猪情况;

然后类似背包转移即可...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-8
using namespace std;
int T,n,m,f[],g[],tot;
double x[],y[];
bool ck(int k,double a,double b)
{
return fabs(a*x[k]*x[k]+b*x[k]-y[k])<eps;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
memset(g,,sizeof g); double a,b;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
if(x[i]==x[j])continue;
a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j]));
b=(y[i]-a*x[i]*x[i])/x[i];
if(a>=)continue;//>=而非> !
tot++;
for(int k=;k<=n;k++)
if(ck(k,a,b))g[tot]|=(<<(k-));
}
for(int i=;i<n;i++)g[++tot]|=(<<i);
sort(g+,g+tot+);
tot=unique(g+,g+tot+)-g-;
memset(f,0x3f,sizeof f); f[]=;
for(int i=;i<(<<n);i++)
for(int j=;j<=tot;j++)
f[i|g[j]]=min(f[i|g[j]],f[i]+);
printf("%d\n",f[(<<n)-]);
}
return ;
}

洛谷P2831 愤怒的小鸟——贪心?状压DP的更多相关文章

  1. 2018.11.02 洛谷P2831 愤怒的小鸟(状压dp)

    传送门 状压一眼题. 直接f[i]f[i]f[i]表示未选择状态为iii时的最小次数. 然后考虑现在怎么转移. 显然可以直接枚举消掉某一个点或者某两个点,复杂度O(n22n)O(n^22^n)O(n2 ...

  2. 洛谷P3959 宝藏(状压dp)

    传送门 为什么感觉状压dp都好玄学……FlashHu大佬太强啦…… 设$f_{i,j}$表示当前选的点集为$i$,下一次要加入的点集为$j$时,新加入的点和原有的点之间的最小边权.具体的转移可以枚举$ ...

  3. 洛谷 P3112 后卫马克 —— 状压DP

    题目:https://www.luogu.org/problemnew/show/P3112 状压DP...转移不错. 代码如下: #include<iostream> #include& ...

  4. 【洛谷4941】War2 状压Dp

    简单的状压DP,和NOIP2017 Day2 找宝藏 代码几乎一样.(比那个稍微简单一点) f[i][j] ,i代表点的状态,j是当前选择的点,枚举上一个选到的点k 然后从f[i-(1<< ...

  5. 洛谷 3959 宝藏——枚举+状压dp

    题目:https://www.luogu.org/problemnew/show/P3959 原来写了个不枚举起点的状压dp. #include<iostream> #include< ...

  6. 洛谷$P3959\ [NOIp2017]$ 宝藏 状压$dp$

    正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j} ...

  7. 洛谷 P1433 吃奶酪 状压DP

    题目描述 分析 比较简单的状压DP 我们设\(f[i][j]\)为当前的状态为\(i\)且当前所在的位置为\(j\)时走过的最小距离 因为老鼠的坐标为\((0,0)\),所以我们要预处理出\(f[1& ...

  8. 洛谷P2473奖励关——状压DP

    题目:https://www.luogu.org/problemnew/show/P2473 还是对DP套路不熟悉... 像这种前面影响后面,而后面不影响前面的问题就应该考虑倒序递推: 看n只有15那 ...

  9. P2831 愤怒的小鸟(状压dp)

    P2831 愤怒的小鸟 我们先预处理出每个猪两两之间(设为$u,v$)和原点三点确定的抛物线(当两只猪横坐标相等时显然无解) 处理出$u,v$确定的抛物线一共可以经过多少点,记为$lines[u][v ...

随机推荐

  1. LeetCode(4)Median of Two Sorted Arrays

    题目 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  2. IDEA常用插件记录

    让我们来记录一下常用的IDEA插件:(从其他博客中取了许多图片,出处见图片水印) 1.JRebel for IntelliJ 热部署神器2.Free MyBatis plugin 实现dao层方法与x ...

  3. CodeForcesGym 100212E Long Dominoes

    Long Dominoes Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on CodeForcesGym. ...

  4. pdf & watermark & puppeteer

    pdf & watermark & puppeteer background image https://en.wikipedia.org/wiki/Watermark pdf &am ...

  5. 【NOIP2016】蚯蚓(单调队列)

    题意: 思路: 我们发现,对于任意两次切割i和j,i<j,在进行完第j次切割后,第i次切割的u/v部分一定大于等于第j次切割的u/v部分,第i次的1-u/v部分也一定大于等于第j次的1-u/v部 ...

  6. SPOJ NSUBSTR (后缀自动机)

    SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...

  7. Ubuntu12.04之修改密码

    Ubuntu 12.04 默认root没有密码 修改密码方式如下: test@localhost:~$ sudo passwd root [sudo] password for test: 输入新的 ...

  8. Java并发包——使用新的方式创建线程

    Java并发包——使用新的方式创建线程 摘要:本文主要学习了如何使用Java并发包中的类创建线程. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520/p/ ...

  9. 【.Net 学习系列】-- .Net 指定时间段内定时执行的Windows服务(System.Threading.Thread)

    创建一个Windows服务项目:解决方案(右击)——> 添加 ——> 新建项目——>项目类型选择Windows——>模板选择Windows服务 ,如图: 编写Windows服务 ...

  10. python函数值传递还是引用传递

    c/c++中有值传递引用传递的区别.但是python中是值传递还是引用传递呢?首先看python中对变量的定义 "python中变量是指向某个内存的, 而内存中的内容是不可变的." ...