zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    《.Net之美》样章 1.1 理解泛型(转载)
    jQuery&JSON~~
    TreeView绑定XML
    TreeView 的 CheckBox 被点击时的引发页面回发事件
    开发中巧用Enum枚举类型
    今天开始学习Python
    获取天气预报
    ORACLE数据库备份
    Eclipse配置Tomcat
    ORACLE常见错误及解决办法
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4959439.html
Copyright © 2011-2022 走看看