计算几何+状压DP愤怒的小鸟

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算几何+状压DP愤怒的小鸟相关的知识,希望对你有一定的参考价值。

本来觉得挺简单的一道题却因为没考虑a>=0的情况而调试了一个上午,看来留给思考的时间应该更多一些,等各种特殊情况都想好之后再开始写代码

总之NOIP2016的题都做完啦

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef double db;
 7 typedef pair<db,db> P;
 8 int t,n,m,f[1<<18],g[18][18];
 9 db a,b,eps=1e-8;
10 P p[18];
11 int dbcmp(db a)
12 {
13     return a<-eps?-1:a>eps?1:0;
14 }
15 void pre()
16 {
17     int s;
18     db x1,x2,y1,y2,x3,y3,a,b;
19     for (int i=0;i<n;i++)
20         for (int j=i+1;j<n;j++)
21         {
22             x1=p[i].first,y1=p[i].second,x2=p[j].first,y2=p[j].second;
23             if (x1==x2) continue;
24             a=(x1/x2*y2-y1)/(x1*(x2-x1)),b=y1/x1-a*x1;
25             if (dbcmp(a)>=0) continue;
26             s=(1<<i)+(1<<j);
27             for (int k=j+1;k<n;k++)
28             {
29                 x3=p[k].first,y3=p[k].second;
30                 if (dbcmp(a*x3*x3+b*x3-y3)==0) s+=(1<<k);
31             }
32             g[i][j]=s;
33         }
34 }
35 int main()
36 {
37     scanf("%d",&t);
38     while(t--)
39     {
40         memset(f,0x7f,sizeof(f));
41         memset(g,0,sizeof(g));
42         scanf("%d%d",&n,&m);
43         for (int i=0;i<n;i++) scanf("%lf%lf",&a,&b),p[i]=P(a,b);
44         sort(p,p+n);
45         pre();
46         f[0]=0;
47         for (int i=0;i<(1<<n)-1;i++)
48         {
49             int j=0; 
50             while((1<<j)&i) j++;
51             for (int k=j+1;k<n;k++)
52                 if (((1<<k)&i)==0)
53                     f[i|g[j][k]]=min(f[i|g[j][k]],f[i]+1);
54             f[i|(1<<j)]=min(f[i|(1<<j)],f[i]+1);
55         }
56         printf("%d\n",f[(1<<n)-1]);
57     }
58 } 

 

以上是关于计算几何+状压DP愤怒的小鸟的主要内容,如果未能解决你的问题,请参考以下文章

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

P2831 愤怒的小鸟(状压dp)

愤怒的小鸟 NOIP2016 提高组 状压dp

P2831 愤怒的小鸟

状压DP之愤怒的小鸟

[luoguP2831] 愤怒的小鸟(状压DP)