• Lightoj 1018


    题目链接:

      Lightoj 1018 - Brush (IV) 

    题目描述:

      有n个点,问最少用几条无线长的线段把这n个点全部覆盖起来?
    解题思路:
      n最大是16,就把所有的线段预处理出来用二进制保存下来,对每个状态枚举每条线段,然后就TLE,TEL,TEL。
      其实应该换一种枚举方式,先预处理出来每条线段,对每一个状态选择两个不在状态的点,然后画以两个点为端点的线,来进行状态转移。这个题目最重要的优化在于如何挑选不在状态的两个点,测试实力比较多,我们可以预处理出来每个状态未覆盖的点。

     1 #include <cmath>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <string>
     6 #include <iostream>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 typedef long long LL;
    11 const int maxn = 16;
    12 const int INF = 0x3f3f3f3f;
    13 struct node
    14 {
    15     int x, y;
    16 }p[maxn];
    17 
    18 vector <int> G[70000];
    19 int dp[1<<16], line[maxn][maxn];
    20 
    21 bool judge (int x, int y, int z)
    22 {
    23     return (p[x].x - p[y].x)*(p[x].y - p[z].y) == (p[x].y - p[y].y)*(p[x].x - p[z].x);
    24 }
    25 
    26 int main ()
    27 {
    28     int T;
    29 
    30     for (int i=0; i<70000; i++)
    31         for (int j=0; j<maxn; j++)
    32             if ((i&(1<<j)) == 0)
    33                 G[i].push_back(j);
    34 
    35     scanf ("%d", &T);
    36 
    37     for (int t=1; t<=T; t++)
    38     {
    39         int n;
    40         scanf ("%d", &n);
    41         memset (dp, INF, sizeof(dp));
    42         memset (line, 0, sizeof(line));
    43 
    44         for (int i=0; i<n; i++)
    45         {
    46             scanf ("%d %d", &p[i].x, &p[i].y);
    47             line[i][i] = (1<<i);
    48         }
    49         for (int i=0; i<n; i++)
    50             for (int j=i+1; j<n; j++)
    51             for (int k=0; k<n; k++)
    52         {
    53             if (!judge (i, j, k))   continue;
    54             line[i][j] |= 1<<k;
    55         }
    56 
    57         int cnt = (1<<n) - 1;
    58         dp[0] = 0;
    59         for (int i=0; i<cnt; i++)
    60         {
    61             int x = G[i][0];
    62             for (int j=0; j<G[i].size(); j++)
    63             {
    64                 int y = G[i][j];
    65                 dp[i|line[x][y]] = min (dp[i|line[x][y]], dp[i]+1);
    66             }
    67         }
    68         printf ("Case %d: %d
    ", t, dp[cnt]);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    作业
    作业
    [转]C语言指针 之 函数指针
    iOS 隐私政策
    微信小程序成长记录(一)
    ios 用信号量控制多个异步网络请求
    ios 利用cocapods创建私有库
    ios 整理获取设备相关信息
    ios_scrollView顶部图片下拉放大
    ios 在项目中使用文字ttf文件
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4959439.html
Copyright © 2020-2023  润新知