題目簡述spa
給定一個長度爲n的序列,每一個數值的範圍爲[-1,40],-1能夠替換成0~40之間的數,要求你求出符合如下條件的序列有多少個?code
一、每一個數都是0~40之間的數blog
二、對於每個數A[i],都須要小於等於前面全部數的算術平均值,及 對於 i, 1 <= i < N, 須要知足 A[i] <= (A[0] + A[1] + ... + A[i-1]) / iget
三、序列中不存在三個連續的數恰好是嚴格遞減的it
題目作法class
dp[i][j][k][f]表示當前第i個數和爲j,第i-1個數爲k,f表示i-2是否小於i-1的符合要求的序列總個數,時間複雜度爲O(n^5)top
代碼:di
1 int dp[45][2000][45][2]; 2 class FoxAverageSequence 3 { 4 public: 5 int theCount(vector <int> seq) 6 { 7 memset(dp, 0, sizeof(dp)); 8 int n = seq.size(); 9 if (seq[0] == -1) 10 for (int i = 0; i <= 40; i++) dp[0][i][i][0] = 1; 11 else dp[0][seq[0]][seq[0]][0] = 1; 12 for (int i = 1; i < n; i++) 13 for (int j = 0; j <= 1600; j++) 14 for (int k = 0; k <= 40; k++) 15 for (int f = 0; f < 2; f++) 16 { 17 int num = seq[i]; 18 if (dp[i - 1][j][k][f]) 19 { 20 int tj = j + num, tf = num < k ? 1 : 0; 21 if (num == -1) 22 { 23 for (int a = 0; a <= 40; a++) 24 { 25 tf = a < k ? 1 : 0; 26 tj = j + a; 27 if (f && tf) continue; 28 if (a * i > j) break; 29 dp[i][tj][a][tf] += dp[i - 1][j][k][f]; 30 dp[i][tj][a][tf] %= MOD; 31 32 } 33 34 } 35 else 36 { 37 if (f && tf) continue; 38 if (num * i > j) continue; 39 dp[i][tj][num][tf] += dp[i - 1][j][k][f]; 40 dp[i][tj][num][tf] %= MOD; 41 } 42 } 43 } 44 int ans = 0; 45 for (int i = 0; i <= 1600; i++) 46 for (int j = 0; j <= 40; j++) 47 { 48 ans += dp[n - 1][i][j][0]; 49 ans %= MOD; 50 ans += dp[n - 1][i][j][1]; 51 ans %= MOD; 52 } 53 printf("%d\n",ans); 54 return ans; 55 56 } 57 };