zoukankan      html  css  js  c++  java
  • luogu2831 [NOIp2016]愤怒的小鸟 (状压dp)

    由范围可以想到状压dp

    两个点(再加上原点)是可以确定一个抛物线的,除非它们解出来a>=0,在本题中是不合法的

    这样的话,我们可以预处理出由任意两个点确定的抛物线所经过的所有的点(要特别规定一下自己和自己确定的抛物线只经过自己)

    然后设状态s表示目前已经有哪些点被击中了,然后我们钦定这次就要打那个最小的还没击中的点(因为吃枣都要打的嘛),再枚举出另一个还没经过的点,就能得到转移方程

    $f[s|line[i][j]]=max{f[s]+1}$,其中$line[i][j]$表示i、j两点确定的抛物线经过的所有的点,i是s中还未击中的最小的点

    复杂度是$O(n2^n)$

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define lowb(x) ((x)&(-(x)))
     4 #define REP(i,n0,n) for(i=n0;i<=n;i++)
     5 #define PER(i,n0,n) for(i=n;i>=n0;i--)
     6 #define MAX(a,b) ((a>b)?a:b)
     7 #define MIN(a,b) ((a<b)?a:b)
     8 #define CLR(a,x) memset(a,x,sizeof(a))
     9 #define rei register int
    10 using namespace std;
    11 typedef long long ll;
    12 const int maxn=20,maxs=1000000;
    13 
    14 inline ll rd(){
    15     ll x=0;char c=getchar();int neg=1;
    16     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    17     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    18     return x*neg;
    19 }
    20 
    21 int N;
    22 double pos[maxn][2];
    23 int line[maxn][maxn];
    24 int f[maxs],bin[maxn];
    25 
    26 inline bool eq(double a,double b){return fabs(a-b)<=1e-8;}
    27 inline void getab(double &a,double &b,double x1,double y1,double x2,double y2){
    28     a=(x2*y1-x1*y2)/(x1*x2*(x1-x2));
    29     b=(x1*x1*y2-x2*x2*y1)/(x1*x2*(x1-x2));
    30 }
    31 
    32 int main(){
    33     // freopen("testdata.in","r",stdin);
    34     int i,j,k;
    35     for(i=1,j=1;i<=19;i++,j<<=1) bin[i]=j;
    36     for(int T=rd();T;T--){
    37         N=rd();rd();
    38         for(i=1;i<=N;i++) scanf("%lf%lf",&pos[i][0],&pos[i][1]);
    39         for(i=1;i<=N;i++){
    40             for(j=i+1;j<=N;j++){
    41                 double a,b;getab(a,b,pos[i][0],pos[i][1],pos[j][0],pos[j][1]);
    42                 
    43                 int s=0;
    44                 if(a<0){
    45                     for(k=1;k<=N;k++ ){
    46                         if(eq(a*pos[k][0]*pos[k][0]+b*pos[k][0],pos[k][1])){
    47                             s|=bin[k];
    48                         }
    49                     }
    50                 }
    51                 line[i][j]=s;
    52                 // cout<<a<<" "<<b<<" "<<i<<" "<<j<<" "<<bitset<20>(s)<<endl;
    53             }line[i][i]=bin[i];
    54         }
    55         memset(f,127,sizeof(f));
    56         f[0]=0;
    57         for(i=0;i<bin[N+1]-1;i++){
    58             for(j=1;bin[j]&i;j++);
    59             for(k=j;k<=N;k++){
    60                 if(bin[k]&i) continue;
    61                 f[i|line[j][k]]=min(f[i|line[j][k]],f[i]+1);
    62             } 
    63         }printf("%d
    ",f[bin[N+1]-1]);
    64     }
    65    
    66     return 0;
    67 }
  • 相关阅读:
    14
    12
    11
    js 元素实现全屏和退出全屏功能
    iOS开发之使用苹果测试工具TestFlight(进行内部和外部测试)
    iOS开发之使用fastlane工具实现自动化打包发布
    iOS开发之使用MQTT协议实现远程通讯
    iOS项目功能模块封装SDK使用总结
    iOS技术之SDK开发注意事项
    iOS开发之登录注册系统
  • 原文地址:https://www.cnblogs.com/Ressed/p/9696043.html
Copyright © 2011-2022 走看看