zoukankan      html  css  js  c++  java
  • SRM 501 DIV1 500pt(DP)

    题目简述

    给定一个长度为n的序列,每个数值的范围为[-1,40],-1可以替换成0~40之间的数,要求你求出符合以下条件的序列有多少个?

    1、每个数都是0~40之间的数

    2、对于每一个数A[i],都需要小于等于前面所有数的算术平均值,及 对于 i, 1 <= i < N, 需要满足 A[i] <= (A[0] + A[1] + ... + A[i-1]) / i

    3、序列中不存在三个连续的数刚好是严格递减的

    题目做法

    dp[i][j][k][f]表示当前第i个数和为j,第i-1个数为k,f表示i-2是否小于i-1的符合要求的序列总个数,时间复杂度为O(n^5)

    代码:

     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
    ",ans);
    54         return ans;
    55 
    56     }
    57 };
  • 相关阅读:
    玩转手工测试之客户端产品手工测试提效实践
    接口测试常用工具及测试方法(新手篇)
    我北漂 7 年,再也不打工了!
    测试人如何高效地设计自动化测试框架?
    你这样,测试人员不能活了。。。
    如何优雅地记录操作日志?
    C#String.IndexOf检索字符串中字符出现的次数
    C#基础之数组
    C#基础之is,as关键字
    C#委托与事件
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/4113375.html
Copyright © 2011-2022 走看看