帮忙解决一个DP问题
我正在尝试解决 SPOJ 的问题(链接 ),可以这样简单地描述:给定 n 个间隔,每个间隔都有一个整数开始和结束,并给定最大时间的结束(我们称之为 max_end ),找出有多少种方法可以选择一组覆盖的间隔1...最大结束。间隔可能会重叠。我尝试过DP;首先按结束时间排序,然后 dp[ i ] 是一对,其中 dp[ i ].first 是覆盖 1...end[ i ] last 使用间隔 i 所需的最小间隔数dp[ i ].second 是执行此操作的方法数。这是我的主要 DP 循环:
for( int i = 1; i < n; i ++ ) {
for( int j = 0; j < i; j ++ ) {
if( ! ( x[ j ].end >= x[ i ].start - 1 ) )
continue;
if( dp[ j ].first + 1 < dp[ i ].first ) {
dp[ i ].first = dp[ j ].first + 1;
dp[ i ].second = dp[ j ].second;
}
else if( dp[ j ].first + 1 == dp[ i ].first ) {
dp[ i ].second += dp[ j ].second;
}
}
}
不幸的是,它不起作用。有人可以告诉我哪里有错误吗?提前致谢! :)
I'm trying to solve a problem from SPOJ ( link ), which can be briefly described like this: Given n intervals, each with an integer beginning and end, and given the end with max time ( let's call it max_end ) , find in how many ways you can choose a set of intervals that covers 1...max_end. Intervals may overlap. I tried a DP; first sort by end time, then dp[ i ] is a pair, where dp[ i ].first is the minimum number of intervals needed to cover 1...end[ i ] last using interval i and dp[ i ].second is the number of ways to do it. Here's my main DP loop:
for( int i = 1; i < n; i ++ ) {
for( int j = 0; j < i; j ++ ) {
if( ! ( x[ j ].end >= x[ i ].start - 1 ) )
continue;
if( dp[ j ].first + 1 < dp[ i ].first ) {
dp[ i ].first = dp[ j ].first + 1;
dp[ i ].second = dp[ j ].second;
}
else if( dp[ j ].first + 1 == dp[ i ].first ) {
dp[ i ].second += dp[ j ].second;
}
}
}
Unfortunately, it didn't work. Can somebody please tell me where I have a mistake? Thanks in advance! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定我是否理解您的解决方案想法,但我描述了我的 AC 解决方案:
我使用带有记忆功能的函数,但您可以使用非递归 DP 重写它。
假设我们的间隔位于数组对
a[100] 中;
在哪里
a[i].first 是间隔开始,a[i].second 是间隔结束。
首先按 begin 对该数组进行排序(具有默认对比较器的 stl 排序算法的默认行为)。
现在想象一下,我们从头到尾一个一个地“放置”间隔。
如果当前最后一个间隔是 x 并且前一个间隔是 'prev',则让 f(int x, int prev) 返回完成填充的方式数。
我们将如下计算:
之后我们需要为每对间隔调用此函数,其中第一个从 0 开始,第二个与第一个连接:
之后我们只需要打印 res.
I'm not sure I get your solution idea, but I describe my AC solution:
I'm using function with memorization, but you can re-write it using non-recurcive DP.
Let's say we have our intervals in array
pair a[100];
where
a[i].first is interval begin and a[i].second is interval end.
Sort this array by begin first (default behavior of stl sort algorithm with default pair comparator).
Now imagine that we are 'putting' intervals one by one from beginning to end.
let f(int x, int prev) return the number of ways to finish the filling if currently last interval is x and previous is 'prev'.
we'll calculate it as follows:
After that we need to call this function for every pair of intervals, first of which start at 0 and second is connected with first:
After that we only need to print the res.