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

    解锁屏幕


    这图太毒瘤了, 看了几遍看不懂。

    直接状压, dp(S,i) 表示走完了集合 S, 停在 i 的方案数。

    计算几何水平缺失(

    #include <bits/stdc++.h>
    using namespace std;
    
    const int mo = 1e8 + 7;
    
    int n;
    struct point { int x, y;} p[21]; 
    bool is (point a, point b, point c) {
    	return (b.y - a.y) * (c.x - b.x) == (b.x - a.x) * (c.y - b.y);
    }
    int pop_count[1 << 20], nd[21][21];
    int dp[1 << 20][20];
    
    int main()
    {
    	scanf ("%d", & n);
    	for (int i = 0; i < n; ++ i)
    		scanf ("%d%d", & p[i].x, & p[i].y);
    	for (int i = 1; i < (1 << n); ++ i)	
    		pop_count[i] = pop_count[i >> 1] + (i & 1);
    	for (int i = 0; i < n; ++ i)
    		for (int j = 0; j < n; ++ j)
    		{
    			if (i == j) continue;
    			for (int k = 0; k < n; ++ k)
    			{
    				if (i == k || j == k) continue;
    				if (((p[k].x-p[i].x) * (p[k].x-p[j].x)<0||(p[k].y-p[i].y) * (p[k].y-p[j].y)<0) && is (p[i], p[k], p[j])) nd[i][j] |= 1 << k;
    			}
    		}
    	long long ans = 0ll;
    	for (int i = 0; i < n; ++ i)
    		dp[1 << i][i] = 1;
    	for (int i = 1; i < (1 << n); ++ i)
    	{
    		for (int j = 0; j < n; ++ j)
    			if (dp[i][j] && ((i>>j) & 1))
    			{
    				if (pop_count[i] >= 4) ans += dp[i][j], ans %= mo;
    				for (int k = 0; k < n; ++ k)
    					if (((i>>k) & 1) == 0 && (nd[j][k] & i) == nd[j][k])
    						dp[i | (1 << k)][k] += dp[i][j], dp[i | (1 << k)][k] %= mo;
    			}
    	}
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    重构与单元测试
    10个现代的软件过度设计错误
    连接ORACLE数据库,是否必须要安装oracle客户端
    关于区块链
    为什么K8s会成为主流?
    Devops K8s
    关于UDP协议
    OO第四单元总结
    OO第三单元总结--根据JML写代码
    面向对象电梯系列总结
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14475729.html
Copyright © 2011-2022 走看看