什么时候使用DP?

通常在这些情况下需要使用到 DP Descriptive Programming :

    * Checking/Unchecking all Check Boxes on a web page

    * Setting all the Text Boxes to blank value

    * Selecting the first possible value for every WebRadioGroup

 

下面是一个使用的例子:

Dim oWebChkDesc

Set oWebChkDesc = Description.Create

oWebChkDesc("micclass").value = "WebCheckBox"

oWebChkDesc("html tag").Value = "INPUT"

 

'Get all objects matching this description

Dim allCheck, oCheckBox

Set allCheck = Browser("Web Tours").Page("Web Tours").ChildObjects(oWebChkDesc)

For i = 0 to allCheck.Count - 1

       Set oCheckBox = allCheck(i)

       oCheckBox.Set "ON"

Next

 

 

 



When and Why to use Descriptive programming?

http://knowledgeinbox.com/articles/qtp/descriptive-programming/dp-part-1-overview/

 

Below are some of the situations when Descriptive Programming can be considered useful:

 

1 The objects in the application are dynamic in nature and need special handling to identify the object. The best example would be of clicking a link which changes according to the user of the application, Ex. “Logout <>“. 对象动态变化,需要特殊处理来识别

 

2 When object repository is getting huge due to the no. of objects being added. If the size of Object repository increases too much then it decreases the performance of QTP while recognizing a object. 防止对象库过大导致 QTP 识别对象的性能下降

 

3. When you don’t want to use object repository at all. 不使用 OR 而使用 DP 的场景

Well the first question would be why not Object repository? Consider the following scenario which would help understand why not Object repository

Scenario 1 : Suppose we have a web application that has not been developed yet. Now QTP for recording the script and adding the objects to repository needs the application to be up, that would mean waiting for the application to be deployed before we can start of with making QTP scripts. But if we know the descriptions of the objects that will be created then we can still start off with the script writing for testing 可以在 AUT 未开发出来之前开始 QTP 的脚本编写

Scenario 2 : Suppose an application has 3 navigation buttons on each and every page. Let the buttons be “Cancel”, “Back” and “Next”. Now recording action on these buttons would add 3 objects per page in the repository. For a 10 page flow this would mean 30 objects which could have been represented just by using 3 objects. So instead of adding these 30 objects to the repository we can just write 3 descriptions for the object and use it on any page. 减少添加重复的测试对象

 

4 Modification to a test case is needed but the Object repository for the same is Read only or in shared mode i.e. changes may affect other scripts as well. 采用共享对象库会影响脚本的并发开发

 

5 When you want to take action on similar type of object i.e. suppose we have 20 textboxes on the page and there names are in the form txt_1, txt_2, txt_3 and so on. Now adding all 20 the Object repository would not be a good programming approach. 需要对一组对象进行相同的操作时,用 DP 会比较方便

 

 

<think>嗯,用户问的是区间DP是什么,怎么理解。首先,我得先回忆一下自己学过的动态规划知识。区间DP属于动态规划的一个分支,对吧?动态规划通常用来解决有重叠子问题和最优子结构的问题。那区间DP的特点应该和区间有关,可能涉及到在一个区间内进行状态转移。 区间DP,顾名思义,应该是处理区间上的问题。比如,合并石子、最长回文子序列这类题目。这类问题通常需要枚举区间的起点和终点,或者区间的长度,然后逐步扩大区间,通过合并小区间的最优解来得到大区间的最优解。比如合并石子的题目,每次合并相邻两堆,代价是两堆之和,求总代价最小。这时候可能需要将大区间分成两个小区间,分别计算合并这两个小区间的代价,再加上合并后的总代价。 那用户可能需要一个比较直观的解释,而不是太学术化的定义。应该用例子来说明会更清楚。比如,假设有一个字符串,求它的最长回文子序列长度,这时候可以用区间DP。定义dp[i][j]表示字符串从i到j的最长回文子序列长度。然后状态转移要看s[i]和s[j]是否相等,如果相等,那么dp[i][j] = dp[i+1][j-1] + 2;否则,取dp[i+1][j]和dp[i][j-1]的最大值。这样,通过从小到大的区间长度逐步计算,最终得到整个字符串的解。 那如何理解区间DP的实现步骤呢?通常需要先遍历区间长度,因为大区间的解依赖于更小的区间。比如,先计算所有长度为1的区间,然后长度为2,依此类推,直到覆盖整个问题范围。这样,在计算长度为L的区间时,所有比它小的区间的解已经计算好了,可以直接使用。 可能用户还不太清楚动态规划和区间DP的区别。动态规划有很多类型,比如线性DP、背包问题、树形DP等,而区间DP专注于区间划分。因此,区间DP的关键在于如何将问题分解成左右两个区间的子问题,并将它们的解合并起来。 另外,需要提到常见的应用场景,比如矩阵链乘法、括号匹配问题、分割回文串等。这些都是区间DP的经典例题。可能用户遇到过类似的问题,但不知道属于区间DP的范畴。 在代码实现方面,区间DP通常使用二维数组dp[i][j],其中i和j分别代表区间的起点和终点。循环结构一般是先枚举区间长度len,然后枚举起点i,根据len计算终点j = i + len -1,再枚举分割点k,将区间分成[i,k]和[k+1,j],然后根据状态转移方程计算dp[i][j]。 需要注意的是,初始化的问题。对于区间长度为1的情况,通常需要单独初始化。例如,回文问题中,每个单独的字符都是长度为1的回文,所以dp[i][i] =1。 可能用户会疑惑为什么区间DP需要按长度循环。这是因为在处理大区间时,必须保证其子区间的解已经计算完毕。例如,计算长度为3的区间需要用到长度为2和1的区间的结果,所以必须从小到大处理所有可能的长度。 总结来说,区间DP的理解要点是:问题可以被分解为重叠的区间子问题,状态转移涉及区间的合并或分割,通常需要二维数组存储状态,按区间长度从小到大递推计算。</think>区间动态规划(区间DP)是一种处理**区间或序列问题**的动态规划方法,其核心思想是将大区间的最优解分解为小区间的最优解,通过合并或分割小区间逐步推导出大区间的解。 --- ### **核心理解** 1. **适用场景** 问题需要在一个区间内操作(如合并、分割、匹配等),且**大区间的解依赖于更小区间的解**。 典型问题:合并石子、最长回文子序列、括号匹配、矩阵链乘法等。 2. **状态定义** 通常用 `dp[i][j]` 表示区间 `[i, j]` 的最优解。例如: - 合并石子:`dp[i][j]` 表示合并第 `i` 到第 `j` 堆石子的最小代价。 - 最长回文子序列:`dp[i][j]` 表示字符串 `s[i...j]` 的最长回文子序列长度。 3. **递推思路** 从小区间向大区间递推: - **枚举区间长度** `len`,从长度为 1 的区间开始,逐步扩大到 `n`。 - **枚举区间起点** `i`,根据 `i` 和 `len` 确定终点 `j = i + len - 1`。 - **枚举分割点** `k`,将 `[i, j]` 分割为 `[i, k]` 和 `[k+1, j]`,合并子区间的解。 4. **状态转移方程** 根据具体问题设计,例如: - **合并石子**: ```python dp[i][j] = min(dp[i][k] + dp[k+1][j] + sum(i,j)) # 其中 k 是分割点,sum(i,j) 是合并 [i,j] 的总代价 ``` - **最长回文子序列**: ```python if s[i] == s[j]: dp[i][j] = dp[i+1][j-1] + 2 else: dp[i][j] = max(dp[i+1][j], dp[i][j-1]) ``` --- ### **实现步骤** 1. **初始化** - 处理长度为 1 的区间(如 `dp[i][i] = 0` 或 `1`)。 2. **遍历区间长度** 从小到大遍历 `len`(确保计算大区间时小区间已计算完毕)。 3. **遍历起点和分割点** 对每个 `[i, j]`,遍历所有可能的分割点 `k`,更新状态。 --- ### **示例:合并石子** ```python n = 4 # 石子堆数 stones = [3, 1, 5, 2] # 每堆石子数量 prefix_sum = [0] * (n+1) for i in range(n): prefix_sum[i+1] = prefix_sum[i] + stones[i] dp = [[0]*n for _ in range(n)] for len_ in range(2, n+1): # 枚举区间长度 for i in range(n - len_ +1): j = i + len_ - 1 dp[i][j] = float('inf') for k in range(i, j): # 枚举分割点 cost = prefix_sum[j+1] - prefix_sum[i] # 合并[i,j]的总代价 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + cost) print(dp[0][n-1]) # 输出合并全部石子的最小代价 ``` --- ### **关键点** - **重叠子问题**:不同区间的计算可能重复依赖同一子区间。 - **最优子结构**:大区间的最优解由分割后的子区间最优解推导而来。 - **顺序重要性**:必须按区间长度从小到大递推,确保状态转移可行。 通过逐步分解区间、合并子问题的解,区间DP能高效解决许多复杂序列问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值