bzoj5299: [Cqoi2018] Unlock screen

The 9.2s time is touching, and the boundary WA*2 was not judged well

Seeing that n is so small in this question, of course, consider the state pressure

Let f[i][zt] represent reaching the i-th point, and zt is the state of taking and not taking

Get a li[i][j] to indicate that if i is to be -> j, then which points need to have been taken, this according to the meaning of the question is that the slope is the same and between the two points

Enumerate the status, enumerate the departure and arrival points, and judge whether it is feasible.

O(n^2*2^n), but there are a lot of things that can't be reached, so let's pass it

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=100000007;

struct node
{
    int x,y;
} a [ 30 ];
you who [ 30 ] [ 30 ];
LL f[21][1100000];
int main()
{
    freopen("data.in","r",stdin);
    freopen("1.out","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&a[i].x,&a[i].y);
    
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            int zz=0;
            for(int k=1;k<=n;k++)
                if(k!=i&&k!=j)
                {
                    if(
                    ((a[i].y-a[k].y)*(a[j].x-a[k].x)==(a[j].y-a[k].y)*(a[i].x-a[k].x))
                    &&
                    
                    (
                    ( (a[i].x<=a[k].x)&&(a[k].x<=a[j].x) && (a[i].y<=a[k].y)&&(a[k].y<=a[j].y) )
                    ||
                    ( (a[i].x>=a[k].x)&&(a[k].x>=a[j].x) && (a[i].y>=a[k].y)&&(a[k].y>=a[j].y) )
                    ||
                    ( (a[i].x>=a[k].x)&&(a[k].x>=a[j].x) && (a[i].y<=a[k].y)&&(a[k].y<=a[j].y) )
                    ||
                    ( (a[i].x<=a[k].x)&&(a[k].x<=a[j].x) && (a[i].y>=a[k].y)&&(a[k].y>=a[j].y) )
                    )
                    
                    )zz|=(1<<(k-1));
                }
            li [i] [j] = li [j] [i] = zz;
            li[i][j]|=(1<<(i-1));
            li[j][i]|=(1<<(j-1));
        }
    
    int u=(1<<n)-1;
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)f[i][(1<<(i-1))]=1;
    for(int zt=1;zt<=u;zt++)
    {
        for(int i=1;i<=n;i++)
        {
            if((zt&(1<<(i-1)))>0&&f[i][zt]!=0)
            {                
                for(int j=1;j<=n;j++)
                {
                    if((zt&(1<<(j-1)))>0)continue;
                    if((zt&li[i][j])==li[i][j])
                        f[j][zt|(1<<(j-1))]=(f[j][zt|(1<<(j-1))]+f[i][zt])%mod;
                }
            }
        }
    }
    LL ans=0;
    for(int zt=1;zt<=u;zt++)
    {
        int o=0;
        for(int i=1;i<=n;i++)
            if((zt&(1<<(i-1)))>0)o++;
        if(o>=4)
        {
            for(int i=1;i<=n;i++)
                ans = (ans + f [i] [zt])% mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324845031&siteId=291194637