zoukankan      html  css  js  c++  java
  • [CQOI2018]解锁屏幕

    Luogu4460

    给出(n)个点的坐标,用直线连接至少四个点组成一条折线 , 并且一条直线不能跨过尚未被选中的点 . 求出不同折线的数量

    状压(DP) , 设(f[x][y])为状态为(y)最终点为(x)的方案数 , (bfs)实现即可

    需要预处理出如果要连接(i,j)必须先连接的点 , 然后在转移的时候判断一下能不能这样连

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int INF=1e9+7;
    inline LL read(){
    	register LL x=0,f=1;register char c=getchar();
    	while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    	while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    	return f*x;
    }
    
    const int N=21;
    const int mod=1e8+7;//坑
    
    int X[N],Y[N],a[N][N],f[N][1<<N];
    bool vis[N][1<<N];
    int n,ans;
    queue <pii> q;
    
    inline int add(int x,int y){x+=y;return x>=mod?x-mod:x;}
    
    inline bool legal(int x){
    	int cnt=0;
    	for(;x;x-=x&-x) cnt++;
    	return cnt>=4;
    }
    inline bool onit(int x,int s,int t){
    	if(X[x]<min(X[s],X[t])||X[x]>max(X[s],X[t])||Y[x]<min(Y[s],Y[t])||Y[x]>max(Y[s],Y[t])) return false;
    	return (X[x]-X[s])*(Y[t]-Y[x])==(X[t]-X[x])*(Y[x]-Y[s]);
    }
    inline bool check(int x,int s,int t){
    	return (a[s][t]&x)==a[s][t];
    }
    
    int main(){
    	n=read();
    	for(register int i=1;i<=n;i++) X[i]=read(),Y[i]=read();
    	for(register int i=1;i<=n;i++){
    		for(register int j=1;j<=n;j++)if(j!=i)
    			for(register int k=1;k<=n;k++)if(k!=i&&k!=j)
    				if(onit(k,i,j)) a[i][j]|=1<<(k-1);
    	}
    	for(register int i=1;i<=n;i++){
    		f[i][1<<(i-1)]=1;
    		vis[i][1<<(i-1)]=1;
    		q.push(pii(i,1<<(i-1)));
    	}
    	while(!q.empty()){
    		register int x=q.front().first,y=q.front().second;q.pop();
    		if(legal(y)) ans=add(ans,f[x][y]);
    		for(register int i=1,j=1;i<=n;i++,j<<=1)if(!(j&y)){
    			if(!check(y,i,x)) continue;
    			if(!vis[i][j|y]) vis[i][j|y]=1,q.push(pii(i,j|y));
    			f[i][j|y]=add(f[i][j|y],f[x][y]);
    		}
    	}
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    HDU 2955 Robberies(01背包)
    HDU 2602 Bone Collector(01背包)
    HUST 1352 Repetitions of Substrings(字符串)
    HUST 1358 Uiwurerirexb jeqvad(模拟解密)
    HUST 1404 Hamming Distance(字符串)
    HDU 4520 小Q系列故事――最佳裁判(STL)
    HDU 2058 The sum problem(枚举)
    【破解】修改程序版权、添加弹窗
    HDU 1407 测试你是否和LTC水平一样高(枚举)
    HDU 1050 Moving Tables(贪心)
  • 原文地址:https://www.cnblogs.com/lizehon/p/10644385.html
Copyright © 2011-2022 走看看