zoukankan      html  css  js  c++  java
  • Light OJ 1018

    题目大意:

        一个二维平面上有N个点,一把刷子,刷一次可以把一条线上的所有点都刷掉。问最少刷多少次,可以把全部的点都刷完
    状态压缩DP, 用记忆化搜索来写, 需要有个优化不然会超时。
    ========================================================================================
     
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    #define Max(a,b) (a>b?a:b)
    const int INF = 1e9+7;
    const int maxn = 20;
    const int MOD = 9973;
    int Line[maxn][maxn];
    int dp[70000], n;
    struct node
    {
        int x, y;
    } P[maxn];
    
    int DFS(int sta)
    {
        if(dp[sta] != - 1)
            return dp[sta];
        dp[sta] = INF;
        int cnt = 0;
        for(int i=0; i<n; i++)
            if( (sta&(1<<i)) ) cnt ++;
    
        if(cnt == 0)
            return dp[sta] = 0;
        else if(cnt <= 2)
            return dp[sta] = 1;
    
    
        for(int a=0; a<n; a++)
        {
            if( (sta&(1<<a)) )
            {
                for(int b=a+1; b<n; b++)
                {
                    if((sta&(1<<a)) == 0 ) continue;
                    int newSta = (sta|Line[a][b]) - Line[a][b];
                    dp[sta] = min(dp[sta], DFS(newSta) + 1);
                }
                break;///此处是优化
            }
        }
        return dp[sta];
    }
    
    int main()
    {
        int T, Lim, cas = 1;
        scanf("%d", &T);
        while(T --)
        {
            memset(dp, -1, sizeof(dp));
            memset(Line, 0, sizeof(Line));
            scanf("%d",&n);
            for(int i=0; i<n; i++)
                scanf("%d %d", &P[i].x, &P[i].y);
    
            for(int i=0; i<n; i++)
            {
                Line[i][i] = (1<<i);
                for(int j=i+1; j<n; j++)
                {
                    for(int k=0; k<n; k++)
                    {
                        if( (P[i].y-P[j].y)*(P[i].x-P[k].x) == (P[i].y-P[k].y)*(P[i].x-P[j].x) )
                            Line[i][j] += (1<<k);
                    }
                    Line[j][i] = Line[i][j];
                }
    
            }
            dp[0] = 0;
            Lim = (1<<n)-1;
            printf("Case %d: %d
    ",cas ++ , DFS(Lim));
        }
        return 0;
    }
  • 相关阅读:
    Ajax和Jsonp的工作原理,以及区别。
    git与GitHub
    Cookie的作用以及封装的方法
    关于angular-route后获取路由标签的一些问题
    javascriptDOM节点
    字符串转化为对象的方法
    将"goOd gooD stUdy dAy dAy up"每个单词的首字母转换成大写其余还是小写字母
    利用HashSet对list集合去重
    集合之Iterator迭代器
    java常用API之System类
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4904862.html
Copyright © 2011-2022 走看看