SRM 501 DIV1 500pt(DP)

題目簡述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 };
相關文章
相關標籤/搜索