HDU 4455 Substrings dp

给定一个序列,个数为n。再给出一系列w;对于每个w,求序列中,所有长度为w的连续子串中的权值和,子串权值为子串中不同数字的个数。

dp[i]表示w=i时所求的答案。dp[1]=n,这个很容易知道,dp[2]中的子串就是删去dp[1]中最后一个子串,再每个子串加上其之后的那个数,以此类推。

对于dp[i-1]推dp[i],加上的那部分:只有当这个数与它前面同值数最短距离大于等于i时才会加权值,否则会重复而不加。

所以可以推出递推式:dp[i]=dp[i-1]-lnc[i-1]+sum。


所以关键点有二:

1.求要删去的最后一个子串的权值,这个for循环一遍就可以,lnc[i]表示w=i的最后一个子串权值。

2.难的就是求加上一个数后所加的权值:令add[i]表示一个数与它前面值相同的数的最近距离,这也能循环一遍存下来。递推求解时,加上sum


如:

3 3 3 4 2 3 3 5

3 3 4 2 3 3 5

3 4 2 3 3 5

4 2 3 3 5

2 3 3 5

3 3 5

3 5

5


给出两组测试数据:

input
8
3 3 3 4 2 3 3 5
8
1 2 3 4 5 6 7 8
output

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值