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

    状压这个东西好像没有什么能优化的高级东西,像什么斜率优化,单调队列在状压的优化上都很少见

    而最常见的状压优化就是预处理优化了,

    这道题就预处理一下所有点对之间连线上的点,之后压成状态就能做到(O(2^n*n^2))

    这道题的状态就非常简单了,就是一个小学生状压(dp[i][S])状态为(S)时最后一个点是(i)的方案数

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define min(a,b) ((a)<(b)?(a):(b))
    #define max(a,b) ((a)>(b)?(a):(b))
    #define re register
    #define lowbit(x) ((x)&(-x))
    #define eps 1e-6
    const int mod=100000007;
    int n;
    int dp[21][1048577];
    int can[21][21];
    inline int read()
    {
    	char c=getchar();
    	int x=0,r=1;
    	while(c<'0'||c>'9') 
    	{
    		if(c=='-') r=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9')
    		x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x*r;
    }
    inline int check(double x,double y)
    {
    	if(x+eps>y&&x-eps<y) return 1;
    	return 0;
    }
    int X[21],Y[21];
    inline int same(int a,int b,int c)
    {
    	if(X[c]<min(X[a],X[b])||X[c]>max(X[a],X[b])||Y[c]>max(Y[a],Y[b])||Y[c]<min(Y[a],Y[b])) return 0;
    	if(X[a]==X[c]) return X[b]==X[c];
    	if(X[b]==X[c]) return X[a]==X[c];
    	return (Y[a]-Y[c])*(X[b]-X[c])==(Y[b]-Y[c])*(X[a]-X[c]);
    }
    inline int cnt(int x)
    {
    	int tot=0;
    	while(x) tot++,x-=lowbit(x);
    	return tot;
    }
    int main()
    {
    	n=read();
    	for(re int i=1;i<=n;i++)
    		X[i]=read(),Y[i]=read();
    	int N=(1<<n)-1;
    	for(re int i=1;i<=n;i++)
    		for(re int j=i+1;j<=n;j++)
    		{
    			can[i][j]=can[j][i]=N;
    			for(re int k=1;k<=n;k++)
    				if(k!=i&&k!=j&&same(i,j,k)) can[i][j]^=(1<<(k-1)),can[j][i]^=(1<<(k-1));
    		}
    	for(re int i=1;i<=n;i++)
    		dp[i][1<<(i-1)]++;
    	for(re int i=1;i<N;i++)
    		for(re int j=1;j<=n;j++)
    			if(dp[j][i]&&(i&(1<<(j-1))))
    			{
    				for(re int k=1;k<=n;k++)
    				if(!(i&(1<<(k-1)))&&((can[j][k]|i)==N)) 
    					dp[k][i|(1<<(k-1))]=(dp[k][i|(1<<(k-1))]+dp[j][i])%mod;
    			}
    	int ans=0;
    	for(re int i=1;i<=N;i++)
    	if(cnt(i)>=4) 
    		for(re int j=1;j<=n;j++) 
    			ans=(ans+dp[j][i])%mod;
    	std::cout<<ans;
    	return 0; 
    }
    
    
  • 相关阅读:
    确保EF上下文线程内唯一
    linq的join
    编码:隐匿在计算机软硬件背后的语言
    EF删除数据
    插入数据返回主键值用 output inserted.UId
    Fancybox丰富的弹出层效果
    回车登录
    “:Choose a destination with a supported architecture in order to run on this device.”
    How to Enable Multi-Touch
    How does CCFileUTils::fullPathForFilename work
  • 原文地址:https://www.cnblogs.com/asuldb/p/10205729.html
Copyright © 2011-2022 走看看