我正在努力改善DP并且已经遇到了一些练习问题。请看this one。我几乎没有想到它的解决方案,但它只是在点点滴滴。我无法将它们连接在一起并提出适当的算法。如何通过动态编程有效地解决这个问题?附:这不是正在进行的比赛或任何类型的任务的一部分。这只是过去比赛的一个练习题。
简要问题说明:
你给了'n'个不同高度和半径的圆盘。您必须使用这些光盘构建最高的塔,使得每个光盘的半径和高度分别小于其下方光盘的半径和高度。
我尝试了什么:
我有一个数组dp [1 .... n],其中dp [i](1< = i< = n)存储你可以使用范围1中的光盘建造的最高塔的高度。 ..一世。然后对于disc i + 1,有两个选项。我要么使用它,要么我不使用它。所以我从1迭代到i并添加尺寸与disc i + 1不冲突的所有光盘的高度。然后我在光盘i + 1和dp [i]的总和+高度中选择更大的值并将其存储在dp [i + 1]中。显然,这对某些情况不起作用。我不会检查我选择的其他光盘是否相互冲突。不确定它是否可以理解,但这是我能解释的最好的。
答案 0 :(得分:2)
你有正确的方法只需要对这对高度和半径进行排序,一旦你做到了O(n ^ 2)解决方案就可以了。
在每个索引处,您可以根据您选择的前一个元素的事实取出或保留当前元素,您将与def scrape_world():
url = 'http://www.worldstarhiphop.com'
html = requests.get(url, headers=headers)
soup = BeautifulSoup(html.text, 'html5lib')
titles = soup.find_all('section', 'box')
cleaned_titles = [title for title in titles if title.a.get('href') != 'vsubmit.php']
entries = [{'href': url + box.a.get('href'),
'src': box.img.get('src'),
'text': box.strong.a.text,
} for box in cleaned_titles]
return entries
中当前元素{{1}的所有先前元素进行比较}}
我在c ++中编写了一个简单的递归DP代码:
0 to i-1
答案 1 :(得分:1)
由于它是动态编程,您必须查看情况何时重复。如果您允许使用的半径/高度与之前相同,那么答案是相同的。此外,由于问题表明它“小于”,你不必担心两次使用光盘。由于两次使用相同的光盘将被自动排除。
int dp(int allowed_rad, int allowed_height){
if(memo[allowed_rad][allowed_height] == true) //I alread have the answer
return dp[allowed_rad][allowed_height];
memo[allowed_rad][allowed_height] = true;
dp[allowed_rad][allowed_height] = 0; //Initiallizing with zero
int ret = 0;
for(int i = 0; i < n; i++){
if(rad[i] < allowed_rad && height[i] < allowed_height){
int result = height[i] + dp(rad[i], height[i]);
if(result > ret) ret = result;
}
}
//it is possible that 0 is returned if I don't have any more option
return dp[allowed_rad][allowed_height] = ret;
}