您的位置:首页 > 其它

P4242【NOIP2016 DAY2】愤怒的小鸟

2017-09-21 16:35 323 查看


输入格式



输出格式

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

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

题解

状压dp

先两两枚举鸟坐标求出抛物线表达式并枚举可击杀数量,将其视作一个商品存入,然后背包dp。

注意精度 用rep来限制精度查

代码

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 20
#define maxn1 270001
#define maxn2 500
#define inf 1e9
const double rep=1e-7;
struct node{
double x,y;
};
node pos[maxn];
int v[maxn2],f[maxn1];
int t,n,m;
int full;
int num,mc,cnt;
void work()
{
int i,j,m;
double a,b;
cnt=0;
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{

double x1,x2,y1,y2;
x1=pos[i].x;y1=pos[i].y;
x2=pos[j].x;y2=pos[j].y;
a=(y1*x2-y2*x1)/(x2*x1)/(x1-x2);
if(a>=0) continue;
b=y1/x1-a*x1;
int val=0;
cnt++;
for(m=1;m<=n;m++){
if(fabs(a*pos[m].x*pos[m].x+b*pos[m].x-pos[m].y)<=rep){
val|=(1<<(m-1));
}

}

v[cnt]=val;

}
}
for(i=1;i<=n;i++){
v[++cnt]=1<<(i-1);
}
}
void dp()
{
int i,j,k;
int ful=((1<<n)-1);
for(i=1;i<=ful;i++) f[i]=inf;
f[0]=0;
for(i=1;i<=cnt;i++)
{
for(j=0;j<=ful;j++)
{
if(f[j]!=inf){
f[j|v[i]]=min(f[j|v[i]],f[j]+1);
}
}
}
}
int main()
{
int i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%lf%lf",&pos[i].x,&pos[i].y);
work();
dp();
cout<<f[(1<<n)-1]<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: