zoukankan      html  css  js  c++  java
  • [NOIp2016提高组]愤怒的小鸟

    题目大意:
      平面直角坐标系的第一象限有n(n<=18)个点,你可以每次给出一个形如y=ax^2+bx的函数把经过这条函数的点消掉,问消掉所有的点至少要多少函数?

    思路:
      枚举每两个点对,可以唯一确定一条函数,再枚举第三个点,判断一下是否会经过这条函数。
      状态压缩一下记录每条函数能消掉那些点。
      然后就是一个简单的状压DP。
      一开始由于把fabs打成了abs,样例都过不去,调了半个下午。
      洛谷上随便A,UOJ上被Extra数据hack掉了,把eps从1e-7改成1e-10就A了。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=18;
    13 const double eps=1e-10;
    14 struct Point {
    15     double x,y;
    16 };
    17 Point p[N];
    18 int sit[N*N],s;
    19 int f[1<<N];
    20 inline double pow(const double &x) {
    21     return x*x;
    22 }
    23 int main() {
    24     for(register int T=getint();T;T--) {
    25         const int n=getint();getint();
    26         for(register int i=0;i<n;i++) {
    27             scanf("%lf%lf",&p[i].x,&p[i].y);
    28         }
    29         for(register int i=0;i<n;i++) {
    30             sit[i]=1<<i;
    31         }
    32         s=n;
    33         for(register int i=0;i<n;i++) {
    34             for(register int j=i+1;j<n;j++) {
    35                 const double x1=p[i].x,x2=p[j].x,y1=p[i].y,y2=p[j].y;
    36                 if(pow(x1)*x2==pow(x2)*x1) continue;
    37                 const double a=(x2*y1/x1-y2)/(x1-x2)/x2,b=((pow(x2)*y1/pow(x1)-y2)/(pow(x2)/x1-x2));
    38                 if(a>-eps) continue;
    39                 sit[s]=(1<<i)|(1<<j);
    40                 for(register int k=j+1;k<n;k++) {
    41                     if(fabs(a*pow(p[k].x)+b*p[k].x-p[k].y)<eps) sit[s]|=1<<k;
    42                 }
    43                 s++;
    44             }
    45         }
    46         for(register int i=1;i<(1<<n);i++) {
    47             f[i]=1e9;
    48         }
    49         for(register int i=0;i<(1<<n);i++) {
    50             for(register int j=0;j<s;j++) {
    51                 f[i|sit[j]]=std::min(f[i|sit[j]],f[i]+1);
    52             }
    53         }
    54         printf("%d
    ",f[(1<<n)-1]);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    pytorch+tensorboard 安装
    pytorch安装
    255.用队列实现堆栈
    23. 合并K个升序链表(学习了java的自定义比较类)
    21.合并两个有序链表
    138.复制带随机指针的链表
    10个教师必备的资源网站,想要免费地过来看看
    班主任如何管理一个乱班、差班?
    高阶函数_函数柯里化 以及 setState中动态key
    React中的PropTypes详解
  • 原文地址:https://www.cnblogs.com/skylee03/p/7784131.html
Copyright © 2011-2022 走看看