版权声明:虽然博主很菜,但是还是请注明出处(我觉得应该没人偷我的博客) https://blog.csdn.net/qq_43346903/article/details/87875981
简单的状压DP
预处理i到j要经过哪些点然后简单转移
Code:
#include<bits/stdc++.h>
#define mod 100000007
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=1100005;
int we[35],n,m,px[35],py[35],lb[N];
int pre[35][35],f[N][23],ans;
inline void init(){
we[0]=1;
for(int i=1;i<=20;i++) we[i]=we[i-1]<<1;
for(int i=1;i<we[20];i++) lb[i]=lb[i^(i&-i)]+1;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
pre[i][j]=we[i]|we[j];
for(int k=0;k<n;k++){
if(px[k]>max(px[i],px[j])||px[k]<min(px[i],px[j])) continue;
if(py[k]>max(py[i],py[j])||py[k]<min(py[i],py[j])) continue;
if((px[i]-px[j])*(py[i]-py[k])==(px[i]-px[k])*(py[i]-py[j])) pre[i][j]|=we[k];
}
}
}
int main(){
init();
n=read();
for(int i=0;i<n;i++) px[i]=read(),py[i]=read();
init();
for(int i=0;i<n;i++) f[we[i]][i]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<we[n];j++) if(lb[j]==i)
for(int k=0;k<n;k++) if(f[j][k]){
if(i>=4) ans=(ans+f[j][k]%mod)%mod;
for(int l=0;l<n;l++) if(!(we[l]&j)&&lb[(j&pre[k][l])^pre[k][l]]==1) f[j|we[l]][l]=(f[j|we[l]][l]+f[j][k]%mod)%mod;
}
cout<<ans;
return 0;
}