1. 程式人生 > >牛客寒假算法基礎集訓營1 F 小a的子序列

牛客寒假算法基礎集訓營1 F 小a的子序列

註意 3*3 end 三種 技術 div 算法 idt 多少

題目描述

鏈接: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 型,這道題我感覺如果還有類似的我可能還是做不出來。。。。

牛客寒假算法基礎集訓營1 F 小a的子序列