给定一个序列,个数为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