牛客寒假算法基础集训营1 F 小a的子序列

题目描述

链接:https://ac.nowcoder.com/acm/contest/317/F
来源:牛客网

题解:

理解:

例二:
n=3,v=4;
一个数时:4 * 3 = 12;每个数有3种位置
两个数时:C(4,2)=6 , 1*3+2*2+3*1=10 ;每组数有三种位置 *3
三个数时:C(4,3)=4, 2+2+3+6=13;
1 2 3 = 2
1 2 4 = 2
1 3 4 = 3
2 3 4 = 6

题解思路(代入例二):
截止到第一个位置,不论是多少,dp[1][j<=v]=1;
截至到第二个位置,dp[2][1] = 2,{(1,x),(x,1)}
dp[2][2] = 3,{(2,x),(x,2),(1,2)}
dp[2][3] = 5,{(3,x),(x,3),(1,3),(2,3)}
dp[2][4] = 8,{(4,x),(x,4),(1,4),(2,4),(3,4)}

截止到第三个位置,dp[3][1] = 3,{(1,x,x),(x,1,x),(x,x,1)}
dp[3][2] = 6,{(2,x,x),(x,2,x),(x,x,2),(1,2,x),(1,x,2),(x,1,2)}
dp[3][3] = 6 + 8 = 14,(3,x,x)+(1,3,x) = 6
{(2,x,3),(2,3,x),(x,2,3),(1,2,3)} = 2 * 3 + 2 = 8;
dp[3,4] = 14 + 18 = 32;(4,x,x)+(1,4,x)+(2,4,x)+(1,2,4) = 14
{(3,4,x)*3,(1,3,4),(2,3,4)}=3*3+3+6=18;

同时也可以得到:dp[i][1]=i;

 代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 
 5 const ll mod = 1e9 + 7;
 6 ll dp[5005][5005];
 7 int main()
 8 {
 9     int n,v;
10     while(cin >> n >> v)
11     {
12         memset(dp,0,sizeof(dp));
13         ll sum;
14         for(int j = 1;j <= v;j++)
15         dp[1][j] = 1;
16         for(int i = 2;i <= n;i++)
17         {
18             sum = 1;
19             for(int j = 1;j <= v;j++)
20             {
21                 dp[i][j] = (dp[i - 1][j] + sum) % mod;
22                 sum = (sum + dp[i - 1][j] * j) % mod;
23                 //cout << "dp" << i << "," << j << "-->" << dp[i][j] << endl;
24             }
25         }
26         ll res = 0;
27         for(int i = 1;i <= v;i++)
28         res = (res + dp[n][i]) % mod;
29         cout << res << endl;
30     }
31     return 0;
32 }

注意,dp数组也是long long 型,这道题我感觉如果还有类似的我可能还是做不出来。。。。

猜你喜欢

转载自www.cnblogs.com/lu1nacy/p/10355700.html