博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 1087 Super Jumping! Jumping! Jumping! 解题报告
阅读量:5104 次
发布时间:2019-06-13

本文共 2098 字,大约阅读时间需要 6 分钟。

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087

题目本质上要求我们求给定序列的最长的递增序列,由于刚接触DP,所以一开始还把状态方程写错了,还特地看了运筹学和算法导论的动态规划这一部分。以下是错误的解题历程,读者可以忽略这部分“【 】”。

【(sum[i]保存的是当前求得的最大和, d[i]保存的是第i个数,sum[i] = max{sum[i-1], sum[i-1]+d[i]}  条件是: d[i-1] > d[i])。接着写成:sum[i] = sum[i-1]+d[i]  (d[i-1] < d[i]) (注意:这里的d[i-1]不一定紧挨着d[i]的,它表示的是计算前一个最大和状态sum[i-1]时的最后一个数,即为d[i-1],那么当前的最大和sum[i]在满足d[i-1] < d[i]这种情况的时候,只能是sum[i-1]+d[i]了 

比如说这个序列 :   1   5   4   98   7   46   3 

当i指示的是4这个数时,前一个最大和状态sum[i-1]为 6(1+5的结果,此时d[i-1]为5),但当前的d[i]为4,显然不满足d[i-1] < d[i],于是i指向下一个位置,即98这个数,满足d[i-1] < d[i](5 < 98),于是更新新一轮的sum[i],为104(6+98),i继续向后移动,由于再也找不到比98大的数,所以最终结果是104。如果不满足d[i] > d[i-1],那么就一直保存前一个状态s[i-1],直到扫描到序列的最后一个元素。如果这样想,有一种序列是求解不了的,即1 9 4 8 98 110,我写的代码里只能求解1 9 98 110, 不能求解更大的1 4 8 98 110】,无奈之下,看了别人的思路,再加上做01背包(bone collector)的经验,一下子顿悟了。

     正确的状态转移方程:  sum[i] = max{sum[j]} + d[i] (0 <= j < i && d[j] < d[i])

     要多设一个辅助数组是sum[i],它的数组下标是和d[i]的数组下标是一致的。保存的是比当前i小的且排在i前面的最大和,例如选定的dp[3] (98),它可以选的点是下标为  0、 1、 2 的sum值,此时我们是选最大的sum[1](前提是dp[1] < dp[3]),那么加上当前的dp[3],sum[3] = sum[1] + dp[3]了。这里的阶段实质上是如何得到sum[i],而它是与当前的dp[i]和sum[j](j < i)密切相关的。最后再比较sum[i]里的数,最大的那个数即是结果。

     假设还是       1    5     4     98     7      46    3  这个序列

     数组下标i      0    1     2     3      4      5     6

     dp[i]          1    5     4     98     7      46    3

     sum[i]         1    6     5     104    13     59    4

    

1 #include 
2 using namespace std; 3 4 int main() 5 { 6 int dp[1005], sum[1005], i, j, n, maxsum, msum; 7 while (cin >> n && n) 8 { 9 memset(sum, 0, sizeof(sum));10 for (i = 0; i < n; i++)11 scanf("%d", &dp[i]);12 sum[0] = dp[0];13 for (i = 1; i < n; i++)14 { 15 msum = 0;16 for (j = i-1; j >= 0; j--)17 {18 if (msum < sum[j] && dp[i] > dp[j])19 {20 msum = sum[j];21 }22 }23 sum[i] = msum + dp[i]; 24 }25 maxsum = sum[0];26 for (i = 1; i < n; i++)27 if (maxsum < sum[i])28 maxsum = sum[i];29 printf("%d\n", maxsum);30 }31 return 0;32 }

 

     

  

转载于:https://www.cnblogs.com/windysai/archive/2013/05/30/3109428.html

你可能感兴趣的文章
快速幂
查看>>
改善C#公共程序类库质量的10种方法
查看>>
AIO 开始不定时的抛异常: java.io.IOException: 指定的网络名不再可用
查看>>
MyBaits动态sql语句
查看>>
HDU4405(期望DP)
查看>>
拉格朗日乘子法 那些年学过的高数
查看>>
vs code 的便捷使用
查看>>
Spring MVC @ResponseBody返回中文字符串乱码问题
查看>>
用户空间与内核空间,进程上下文与中断上下文[总结]
查看>>
JS 中的跨域请求
查看>>
JAVA开发环境搭建
查看>>
mysql基础语句
查看>>
Oracle中的rownum不能使用大于>的问题
查看>>
[Data Structure & Algorithm] 有向无环图的拓扑排序及关键路径
查看>>
cassandra vs mongo (1)存储引擎
查看>>
Visual Studio基于CMake配置opencv1.0.0、opencv2.2
查看>>
遍历Map对象
查看>>
MySQL索引背后的数据结构及算法原理
查看>>
#Leetcode# 209. Minimum Size Subarray Sum
查看>>
SDN第四次作业
查看>>