zoukankan      html  css  js  c++  java
  • [LightOJ 1018]Brush (IV)[状压DP]

    题目链接:http://lightoj.com/volume_showproblem.php?

    problem=1018
    题意分析:平面上有不超过N个点,如今能够随意方向划直线将它们划去,问:最少要划几次能够把全部的点划去?
    解题思路:我们能够使用集合S表示:有哪些点还没有被划掉,然后转移 dp[s] = min(dp[s &(~line[i][j])]) + 1;这里涉及到line[i][j]的处理,它代表的是在i点和j点构成的直线上一共同拥有几个点,须要预先处理。

    边界条件就是S中集合元素 >0 && <= 2时,肯定是1。元素空时就是0了。


    个人感受:一開始想到的是用s代表当前点没被划过的集合。然后卡在了怎么转移上,想着选两个点遍历着推断这两个点所在直线有几个点。感觉炒鸡麻烦。然后就是翻了别人的题解,看到了预处理这字样。豁然开朗啊~
    详细代码例如以下:

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 20;
    int x[MAXN], y[MAXN], line[MAXN][MAXN], n, dp[1 << 16];
    
    void init()
    {
        memset(line, 0, sizeof line);
        memset(dp, 0x3f, sizeof dp);
        dp[0] = 0;
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
            {
                line[i][j] = (1 << i) | (1 << j);
                int dx = x[j] - x[i], dy = y[j] - y[i];
                for (int k = j + 1; k < n; ++k)
                {
                    int dx2 = x[k] - x[i], dy2 = y[k] - y[i]; //这里我用了向量平行的条件
                    if (dx2 * dy == dy2 * dx)
                        line[i][j] |= (1 << k);
                }
                line[j][i] = line[i][j];
            }
    }
    
    int dfs(int s)
    {
        int& ret = dp[s];
        if (dp[s] < INF) return ret;
        int num = __builtin_popcount(s); //计算s中有几个1.非常好用的函数
        if (num <= 2) return ret = 1;
        int i = 0;
        while (!(s & (1 << i))) ++i; //找出第一个没被删除的点
        for (int j = i + 1; j < n; ++j) //和其他点进行匹配。

    这里匹配次序是不会影响终于结果的 { if (s & (1 << j)) { ret = min(ret, dfs(s&(~line[i][j])) + 1); } } return ret; } int main() { int t; for (int kase = scanf("%d", &t); kase <= t; ++kase) { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d%d", x+i, y+i); init(); printf("Case %d: %d ", kase, dfs((1 << n) - 1)); } return 0; }


  • 相关阅读:
    DOM 与BOM
    尝试json文件导入数据
    js事件监听简介
    js事件简介
    js中的for语句简介
    作业练习正则表达式
    简单总结-BOM
    web前端第三次作业em,fr,rem,px简单解释及颜色表
    web第二次作业练习grid
    web前端课程第一次作业----注册页面代码(2018-9-14)
  • 原文地址:https://www.cnblogs.com/jhcelue/p/6855731.html
Copyright © 2011-2022 走看看