题目链接
解题方法:dp
题目分析
题目大意
给出$n$个数字,使这$n$个数字相加等于$m$,问从这$n$个数字中挑出一部分,使之符合(1) $b_1 \leq b_2 \leq \ldots \leq b_t$
(2) $b_2-b_1 \leq b_3-b_2 \leq \dots \leq bt-b{t-1}$这两个条件,问该序列的长度为多少
解析
拿到题目不难想到是动态规划问题,但是状态转移方程不好想。首先先想,如果形成一个字序列,那么只有可能是序列的第一个数重复取(如果可以的话),所以只需要将数列去重,并且统计出每个数字的出现频率,当我们取某一个数字作为第一个数字的时候,则将结果加入该数字的出现频率。对于后面的数字就可以dp的来找了,并且每个数字只可能出现一次。建立这样一个状态转移方程,$dp[i][j]$表示最后一个数字取$j$位置且倒数第二个位置取$i$位置时的答案数量,所以$dp[i][j] = max ( dp[i][j], dp[k][i] + 1)|k<=i$。写程序的时候还有一个问题,数据范围,题目中只给了这些数字相加的最大和,没有给出$n$的取值范围,其实由题意可以知道,当m<=2^22时,$n$的最大值不到3000,原理就是一个等差数列,相加到2^22时,按公差为$1$算。写dp的for循环时,枚举中间位,再分别向两头跑循环即可。
参考题解:Bestcoder13 1003.Find Sequence(hdu 5064) 解题报告
代码
1 |
|