1 条题解

  • 0
    @ 2026-5-9 15:40:24

    因为 n20n \leq 20,考虑状压。

    先预处理从 ii 号点到 jj 号点一定经过的点,压到一个集合 Si,jS_{i,j} 中。

    fi,jf_{i,j} 表示图案经过的点集为 ii,且最后一个点是 jj 的方案数。

    每次枚举下一个要经过的点,当且仅当这个点之前没被经过,且当前点合下一个点之间的所有点都被经过时才能转移。

    最后统计所有经过至少四个点的状态即可。

    时间复杂度 O(n22n)O(n^2 2^n),当然实际合法的状态转移不会达到这个上限。

    // Problem : P4460 [CQOI2018]解锁屏幕
    // Contest : Luogu Online Judge
    // URL : https://www.luogu.com.cn/problem/P4460
    // Author : StudyingFather
    // Site : https://studyingfather.com
    // Memory Limit : 500 MB
    // Time Limit : 1000 ms
    // Powered by CP Editor (https://github.com/cpeditor/cp-editor)
    
    #include <iostream>
    #include <algorithm>
    #define MOD 100000007
    #define INF 1e9
    #define eqs 1e-7
    using namespace std;
    struct point
    {
     int x,y;
    }p[25];
    int f[2500005][25],ans;
    int g[25][25];
    bool cmp(const point&a,const point&b)
    {
     return a.x<b.x||(a.x==b.x&&a.y<b.y);
    }
    double slope(int x1,int y1,int x2,int y2)
    {
     if(x1==x2)return INF;
     return 1.0*(y1-y2)/(x1-x2);
    }
    int popcount(int x)
    {
     int ans=0;
     while(x)
     {
      ans++;
      x&=(x-1);
     }
     return ans;
    }
    int main()
    {
     int n;
     cin>>n;
     for(int i=1;i<=n;i++)
      cin>>p[i].x>>p[i].y;
     sort(p+1,p+n+1,cmp);
     for(int i=1;i<=n;i++)
      for(int j=i+1;j<=n;j++)
       for(int k=i+1;k<=j-1;k++)
        if(abs(slope(p[i].x,p[i].y,p[k].x,p[k].y)-slope(p[k].x,p[k].y,p[j].x,p[j].y))<=eqs)
         g[i][j]|=(1<<k),g[j][i]|=(1<<k);
     for(int i=1;i<=n;i++)
      f[1<<i][i]=1;
     for(int i=0;i<(1<<(n+1));i++)
      for(int j=1;j<=n;j++)
       if(i&(1<<j))
        for(int k=1;k<=n;k++)
         if((i&(1<<k))==0&&k!=j&&(i&g[j][k])==g[j][k])
          f[i|(1<<k)][k]=(f[i|(1<<k)][k]+f[i][j])%MOD;
     for(int i=0;i<(1<<(n+1));i++)
      if(popcount(i)>=4)
       for(int j=1;j<=n;j++)
        if(i&(1<<j))ans=(ans+f[i][j])%MOD;
     cout<<ans<<endl;
     return 0;
    }
    
    • 1

    信息

    ID
    1339
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    56
    已通过
    17
    上传者