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

 

转载于:https://www.cnblogs.com/valaxy/p/3399782.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值