P9676 [ICPC2022 Jinan R] Skills Solution

P9676 [ICPC2022 Jinan R] Skills Solution

拿到题目之后我们先考虑一个朴素dp:记 fi,0/1/2,x,y 表示第 i 天,我们学习第 1/2/3 个技能,同时按照序号顺延下去的另两个技能分别有 x,y 天未学习的最大经验总和。这很明显是一个 O(n3) 的 dp,转移方程比较简单。我们考虑优化。
第一维明显可以滚动数组滚掉,于是空间复杂度来到了 O(n2)。于是没有什么明显的优化空间了,我们考虑分析特殊性质:
如果我在某一天学习了某项技能,那么我之后一定不能让它的经验值降为 0 ,因为如果这样的话我们很明显在那一天学习其它技能是不劣甚至更优的。于是很明显有一个未学习天数的限制,不难算出这个天数是 2ai,于是时间复杂度降到了 O(n2),可以通过本题。
code

#include <bits/stdc++.h>
using namespace std;

#define Debug printf("ZYC\n")
using Yc = long long;
using pii = pair<Yc, Yc>;

namespace Fast_Read {

inline Yc read() {
  Yc x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}

inline void write(Yc x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
  return;
}
}  // namespace Fast_Read

const Yc zyc = 1000 + 10;
const Yc limit = 210;

using namespace Fast_Read;
#define pc putchar
#define ps puts
#define pr printf
#define mk make_pair

Yc n, a[zyc][3], f[2][3][limit + 10][limit + 10], nxt[3];

inline void chmax(Yc &a, Yc b) { a = max(a, b); }

signed main() {
#define ZYC_
#ifdef ZYC_
  freopen(".in", "r", stdin);
  freopen(".out", "w", stdout);
#endif  // ZYC_

  Yc T = read();
  while (T--) {
    n = read();
    for (Yc i = 1; i <= n; i++)
      for (Yc j = 0; j < 3; j++) a[i][j] = read();
    memset(f, 0, sizeof(f));
    Yc cur = 0;
    for (Yc i = 0; i < n; cur ^= 1, i++) {
      for (Yc j = 0; j < 3; j++) {
        for (Yc k = 0; k < limit && k <= i; k++) {
          for (Yc l = 0; l < limit && l <= i; l++) {
            Yc nx = k ? k + 1 : 0, ny = l ? l + 1 : 0;
            if (nx < limit && ny < limit)
              chmax(f[cur ^ 1][j][nx][ny],
                    f[cur][j][k][l] - nx - ny + a[i + 1][j]);
            if (nx < limit)
              chmax(f[cur ^ 1][(j + 1) % 3][ny][1],
                    f[cur][j][k][l] - ny - 1 + a[i + 1][(j + 1) % 3]);
            if (ny < limit)
              chmax(f[cur ^ 1][(j + 2) % 3][1][nx],
                    f[cur][j][k][l] - nx - 1 + a[i + 1][(j + 2) % 3]);
          }
        }
      }
    }
    Yc ans = 0;
    for (Yc j = 0; j < 3; j++)
      for (Yc k = 0; k < limit && k <= n; k++)
        for (Yc l = 0; l < limit && l <= n; l++) chmax(ans, f[cur][j][k][l]);
    write(ans), ps("");
  }
  return 0;
}
posted @   yxans  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示