zoukankan      html  css  js  c++  java
  • SRM145 DIV1 1000

    一道组合计数的问题,计算符合条件的合法组合个数。

    任意一个合法的path都不是精确的,因为landmarks可以被标记在多个点上。若将landmarks尽可能靠前匹配,path中将不存在任意前后两个相同高度的点A、B,其中B被标记而A没被标记,AB之间也不存在其他标记。否则可以标记A而去掉标记B来使得landmarks的标记情况更加“靠前”。因此题目所求变为计算这种精确的path的个数。

    使用一种分步策略来选择这种组合:

    令(d, h, i, tf) 表示d点高度为h,前i个landmarks已被标记,若tf=1:到达过山顶,否则:还没到到过山顶。

    地势可以升高、降低、不变,当前点可以被标记或者不标记,有如下状态转移方式:

    状态转移:(d, h, i, tf) -> (D, H, I, TF) 

    D = d+1

    H = h-1 or h or h+1

    if landmarks[i] == H then I = i + 1 else I = i

    if H == maxHeight then TF = 1 else TF = tf

    起始状态(0, 0, 0, 0) 终止状态(distance, 0, len(landmarks), 1)

    (状态本身还有其他约束,见题,详见代码)

    一个从起始状态到终止状态的路径就表示一个选择的策略,即对应一个组合,可以看出状态满足无后效性,因此考虑用动态规划来计算

     1 class HillHike:
     2     def _infer(self, d, h, i, tf, q):
     3         if h==0:
     4             if d==self.distance:
     5                 self.s[d][h][i][tf] += q
     6         elif 0<=h<=self.maxHeight:
     7             self.s[d][h][i][tf] += q
     8             
     9     def _createArray(self):
    10         self.s = []
    11         for d in range(0, self.distance+1):
    12             self.s.append([])
    13             for h in range(0, self.maxHeight+1):
    14                 self.s[d].append([])
    15                 for i in range(0, self.landmarks+1):
    16                     self.s[d][h].append([])
    17                     for tf in range(0, 2):
    18                         self.s[d][h][i].append(0)
    19                         
    20         
    21     def numPaths(self, distance, maxHeight, landmarks):
    22         self.distance = distance
    23         self.maxHeight = maxHeight
    24         self.landmarks = len(landmarks)
    25         self._createArray()
    26 
    27         s = self.s
    28         s[0][0][0][0] = 1
    29                 
    30         for d in range(0, distance):
    31             for h in range(0, maxHeight+1):
    32                 for i in range(0, len(landmarks)+1):
    33                     for tf in range(0, 2):
    34                         q = s[d][h][i][tf]
    35                         if q == 0:
    36                             continue
    37 
    38                         D = d + 1
    39                         Hs = [h-1, h, h+1]
    40                         for H in Hs:
    41                             if i < len(landmarks) and landmarks[i] == H:
    42                                 I = i + 1
    43                             else:
    44                                 I = i
    45                             if H == maxHeight:
    46                                 TF = 1
    47                             else:
    48                                 TF = tf
    49                             self._infer(D, H, I, TF, q)
    50         
    51         return s[distance][0][len(landmarks)][1]
    View Code
  • 相关阅读:
    理解Python闭包,这应该是最好的例子
    2021-01-31
    论unity中UI工具与GUI函数
    2021-01-31
    第八届“图灵杯”NEUQ-ACM程序设计竞赛(全题解&&详细)
    第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)全题解
    Go-快速排序
    网络地址转换NAT原理及其作用
    解析私有IP地址和公网IP地址
    first blog
  • 原文地址:https://www.cnblogs.com/valaxy/p/3399782.html
Copyright © 2011-2022 走看看