topcoder srm 520 div1

Posted Only the Strong Survive

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了topcoder srm 520 div1相关的知识,希望对你有一定的参考价值。

problem1 link

设$f[i][j][k]$表示考虑了前$i$道题,剩下时间为$j$,剩下技能为$k$的最大得分.

从小到大计算二元组$(j,k)$的话,在存储上可以省略掉$i$这一维.

problem2 link

首先,不同的提交状态有8种.预计算每一种提交状态的每一个分值的种数,设为$g[mask][score]$.对于$g[mask][score]$的计算,可以枚举$mask$包含的一个题目,设为$i$,其分值为$p_{i}$,那么第$i$道题得分如果为$x$,那么其他$mask^{‘}=mask$^$2^{i}$题目得分为$score-x$,所以$g[mask][score]=\sum_{x=1}^{p_{i}}g[mask^{‘}][score-x]$

最后从前向后考虑每个人的得分.设$f[i][score]$表示前$i$个人的得分降序排列且第$i$个人得分为$score$的方案数.设第$i+1$个人的得分为$y$,由于第$i$个人的得分一定大于$y$,所以$f[i+1][y]=\sum_{x=y+1}^{MaxScore_{i}}f[i][x]$

由于计算数组$g$和$f$都是连续求和,可以通过预处理前缀和或者后缀和来加速记算

problem3 link

 

code for problem1

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


class SRMCodingPhase {
  public:
    int countScore(vector <int> points, vector <int> skills, int luck) {
      vector<vector<int>> f(76, vector<int>(luck + 1, -1));
      f[75][luck] = 0;
      const int b[] = {2, 4, 8};
      for (int i = 0; i < 3; ++ i) {
        const int point = points[i];
        const int skill = skills[i];
        for (int j = 0; j <= 75; ++ j) {
          for (int k = 0; k <= luck; ++ k) {
            if (f[j][k] == -1) {
              continue;
            }
            for (int t = 0; t <= k && t < skill; ++ t) {
              const int last_point = point - b[i] * (skill - t);
              if (last_point <= 0) {
                continue;
              }
              if (skill - t > j) {
                continue;
              }
              f[j - (skill - t)][k - t] = max(f[j - (skill - t)][k - t], last_point + f[j][k]);
            }
          }
        }
      }
      int result = 0;
      for (int j = 0; j <= 75; ++ j) {
        for (int k = 0; k <= luck; ++ k) {
          result = max(result, f[j][k]);
        }
      }
      return result;
    }
};

  

code for problem2

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

#define mod 1000000007
#define MAX_SCORE 200000

int g[8][MAX_SCORE + 1];
int f[20][MAX_SCORE + 1];

class SRMIntermissionPhase {
  public:
    int countWays(vector<int> points, vector<string> description) {
      Initialize(points);

      const int mask0 = GetMask(description[0]);
      for (int i = 0; i <= MAX_SCORE; ++ i) {
        f[0][i] = GetRangeSum(mask0, i, i);
      }
      CalculateSuffixSum(0);
      const int person_number = (int)description.size();
      for (int i = 1; i < person_number; ++ i) {
        const int mask = GetMask(description[i]);
        for (int j = 0; j < MAX_SCORE; ++ j) {
          f[i][j] = (long long)GetRangeSum(mask, j, j) * f[i - 1][j + 1] % mod;
        }
        CalculateSuffixSum(i);
      }
      return f[person_number - 1][0];
    }
  private:

    void CalculateSuffixSum(int idx) {
      for (int i = MAX_SCORE - 1; i >= 0; -- i) {
        Add(f[idx][i], f[idx][i + 1]);
      }
    }
    void CalculatePrefixSum(int idx) {
      for (int i = 1; i <= MAX_SCORE; ++ i) {
        Add(g[idx][i], g[idx][i - 1]);
      }
    }

    int GetMask(const std::string& s) {
      int mask = 0;
      for (int i = 0; i < 3; ++ i) {
        if (s[i] == ‘Y‘) {
          mask |= 1 << i;
        }
      }
      return mask;
    }

    void Initialize(const vector<int>& points) {
      g[0][0] = 1;
      CalculatePrefixSum(0);
      for (int i = 1; i < 8; ++ i) {
        int low_bit = 0;
        for (int j = 0; j < 3; ++ j) {
          if ((i & (1 << j)) != 0) {
            low_bit = j;
            break;
          }
        }
        const int other = i ^ (1 << low_bit);
        const int point = points[low_bit];
        for (int k = 1; k <= MAX_SCORE; ++ k) {
          g[i][k] = GetRangeSum(other, k - point, k - 1);
        }
        CalculatePrefixSum(i);
      }
    }

    int GetRangeSum(int mask, int left, int right) {
      if (left <= 0) {
        return g[mask][right];
      }
      int result = g[mask][right] - g[mask][left - 1];
      if (result < 0) {
        result += mod;
      }
      return result;
    }
    void Add(int &x, int y) {
      x += y;
      if (x >= mod) {
        x -= mod;
      }
    }
};

  

code for problem3

以上是关于topcoder srm 520 div1的主要内容,如果未能解决你的问题,请参考以下文章

topcoder srm 320 div1

topcoder SRM712 Div1 LR

topcoder srm 305 div1

topcoder srm 738 div1 FindThePerfectTriangle(枚举)

topcoder srm 310 div1

topcoder srm 515 div1