Processing math: 100%

ABC159F Knapsack for All Segments

[ABC159F] Knapsack for All Segments

一道很简单的 DP , 但是, 记得取模!!!

对于合法的区间 (l,r) , 它对答案的贡献是 l(nr+1) , 这样我们就可以在转移的过程中计算答案了, 有点费用提前计算的味道.

设状态: f(i,j) 表示在前 i 个数中和为 j 的方案的左端点下标之和.

转移很简单, 只需要特殊处理从 f(i1,0) 转移过来的情况, 然后先转移选第 i 个的情况, 统计答案, 再转移不选的就行了.

code:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar())
    x = (x << 1) + (x << 3) + (ch ^ 48);
  return x * f;
}

const int N = 3e3 + 5, mod = 998244353;

int n, s, a[N];
ll f[N][N], ans;

int main() {
  n = read(), s = read();
  for (int i = 1; i <= n; i++)
    a[i] = read();
  for (int i = 1; i <= n; i++) {
      f[i][a[i]] = (f[i - 1][0] + i) % mod;
    for (int j = a[i] + 1; j <= s; j++)
      f[i][j] = f[i - 1][j - a[i]];
    ans = (ans + f[i][s] * (n - i + 1) % mod) % mod;
    for (int j = 0; j <= s; j++)
      f[i][j] = (f[i][j] + f[i - 1][j]) % mod;
  }
  printf("%lld", ans);
  return 0;
}
posted @   sshadows  阅读(33)  评论(0)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示