zoukankan      html  css  js  c++  java
  • poj 1466 计算直线的交点数

    http://acm.hdu.edu.cn/showproblem.php?pid=1466

      一道dp好题,是我们学校Troy哥在他的动态规划的课件里面的一道习题。这题要求我们找出n条直线可以构成哪几种数量的交点。自己想的时候想到了用当前处理第i条共有j个交点来进行动态规划,是因为显然可以看出前i条直线构成j (0<=j<=(i-1)*i/2) 个交点是必定可以推出前i+1条直线构成j (0<=j<=(i+1)*i/2) 个交点的,但是这个递推关系就不是那么容易找到了。

      见识面还是比较窄,迫于无奈找了一下题解,其中我看到一个这样的转移方程:

    dp[i-r][j] --> dp[i][(i-r)*r+j] (1<=r<i)

    (自己搞的,和原文的有出入,其他题解很多都是写dp[i][j]=(i-r)*r+dp[r][k]

      对于这样的一个方程,我参照别人题解里面所说的,弄不懂...- -    于是我就yy了一下,得出我的见解...希望对初学者的理解有帮助。

      实际上,由方程可以看到其实还有一个算是状态的辅助参数r。这个r的作用是十分的强大,可以将它理解为要在i-r条直线里加上一组r条的平行线,而且这组平行线和原来i-r条线都不平行,所以交上以后就会多出r*(i-r)个交点。如果dp[i-r][j]可取,那么dp[i][(i-r)*r+j]就是可取的了。这样,接下来就是体力劳动了。

      我的代码:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 
     5 #define debug 0
     6 
     7 int min2(int _a, int _b){return _a < _b ? _a : _b;}
     8 int max2(int _a, int _b){return _a > _b ? _a : _b;}
     9 
    10 bool dp[21][191];
    11 
    12 bool solve(){
    13     memset(dp, 0, sizeof(dp));
    14     for (int i = 0; i <= 20; i++){
    15         dp[i][0] = true;
    16     }
    17     for (int i = 2; i <= 20; i++){
    18         for (int j = 1; j < i; j++){
    19             for (int k = 0; k <= 190; k++){
    20                 dp[i][k + j * (i - j)] |= dp[i - j][k];
    21             }
    22         }
    23     }
    24     #if debug
    25     for (int i = 1; i <= 6; i++){
    26         for (int j = 0; j < 20; j++){
    27             printf("%d", dp[i][j]);
    28         }
    29         puts("");
    30     }
    31     #endif
    32 
    33     return true;
    34 }
    35 
    36 int main(){
    37     int n;
    38 
    39     solve();
    40     while (~scanf("%d", &n)){
    41         int i = 0, end = n * (n - 1) >> 1;
    42 
    43         for (; i < end; i++){
    44             if (dp[n][i]) printf("%d ", i);
    45         }
    46         printf("%d\n", end);
    47     }
    48 
    49     return 0;
    50 }

    ——written by Lyon

  • 相关阅读:
    CRUD工程师——嵌入式Web容器
    CRUD工程师——SpringBoot启动原理
    CRUD工程师——日志
    CRUD工程师——慢SQL
    CRUD工程师——索引
    前端专业术语: shim 和 Polyfill,了解下
    H5之postMessage 。实现跨域
    摘抄详细的VUE生命周期
    如何在不使用三大地图的KEY和相关组件的情况下,直接传参数到相关的H5地图
    Mac下通过brew安装指定版本的nodejs
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_1466_Lyon.html
Copyright © 2011-2022 走看看