牛客寒假算法基础集训营1 小a的子序列 (区间DP)

小a的子序列 

题目链接:https://ac.nowcoder.com/acm/contest/317/F

题目描述

小a有一个长度为nn的序列,但是他忘了这个序列的样子,他只记得序列中的数大小在[1,V][1,V]内
你可以任意选择一些位置,并给它们赋值来组成一段子序列,需要满足序列中的数严格递增
一段子序列的“萌值”定义为序列中除最大数外所有数的乘积,若只有11个数则为11
他想请你求出所有合法子序列的“萌值”的和
不同子序列的定义为:存在某个值不同 或 在原序列中的位置不同
输出答案对10^9+7取模

输入描述:

两个数n,V

输出描述:

一个整数表示答案
示例1

输入

2 2

输出

5

说明

若X表示不选该位置,那么合法的方案有
1 X = 1
X 1 = 1
1 2 = 1
X 2 = 1
2 X = 1
示例2

输入

3 4

输出

55

说明

样例2
解释:https://paste.ubuntu.com/p/xQwvD7Q3mX/

备注:

保证2n,V5000
 1 import java.util.Scanner;
 2  
 3 public class Main {
 4     static long [][] dp = new long [5005][5005];
 5     static long mod = 1000000000+7;
 6     public static void main(String[] args) {
 7         Scanner cin = new Scanner(System.in);
 8         int n,v;
 9         n = cin.nextInt();
10         v = cin.nextInt();
11         //dp[i][j]表示长度为i,最大值为j的萌值的和
12         for(int i=1;i<=v;i++) {
13             dp[1][i] = 1;
14         }
15         for(int i=2;i<=n;i++) {
16             long sum = 1;
17             for(int j=1;j<=v;j++) {
18                 dp[i][j] = (dp[i-1][j]+sum)%mod;
19                 //对于下一轮的j来说,其中最大的数为当前的j,所以dp[i-1][j]要乘上j
20                 sum = (sum+dp[i-1][j]*j)%mod;
21             }
22         }
23         long ans = 0;
24         for(int i=1;i<=v;i++) {
25             ans = (ans + dp[n][i])%mod;
26         }
27         System.out.println(ans);
28     }
29 }

 

 
posted @ 2019-02-12 17:52  *starry*  阅读(176)  评论(0编辑  收藏  举报