Submission #53067292


Source Code Expand

#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<cassert>
#include<random>
#include<set>
#include<map>
#include<cassert>
#include<unordered_map>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=1<<30;
const ll INF=1LL<<62;
typedef pair<ll,ll> P;
typedef pair<int,P> PP; 


const int mod = 998244353;
struct mint {
  long long x; // typedef long long long long;
  mint(long long x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}//後ろのconstはメンバxを変更しないことを示す
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  bool operator==(const mint a) const {return a.x==x;}
  mint pow(long long t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }

  // for prime mod
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};

std::istream& operator>>(std::istream& is, mint& a) { return is >> a.x;}
std::ostream& operator<<(std::ostream& os, const mint& a) { return os << a.x;}



struct combination {
  std::vector<mint> fact, ifact;
  combination(int n):fact(n+1),ifact(n+1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n]*ifact[k]*ifact[n-k];
  }
};

enum{
  NONE, //まだ左端を始めてすらいない
  ON,//継続中
  FINISH,//右端も選択済み
};


mint dp[3005][3005][4];


int main(){
    int N,S;
    cin>>N>>S;
    vector<int> A(N);
    for(int i=0;i<N;i++){
        cin>>A[i];
    }

   

    dp[0][0][NONE]=1;
    for(int i=0;i<N;i++){
      for(int j=0;j<=S;j++){

        {
          dp[i+1][j][ON]+=dp[i][j][NONE];//新たに始める.A[j]を採用しない
          if(j+A[i]<=S){
            dp[i+1][j+A[i]][ON]+=dp[i][j][NONE];//新たに始める
          }
          dp[i+1][j][NONE]+=dp[i][j][NONE];
        }
        
        {
          if(j+A[i]<=S){
            dp[i+1][j+A[i]][ON]+=dp[i][j][ON];//継続が継続したまま A[i]を採用する
          }
          dp[i+1][j][ON]+=dp[i][j][ON];//継続が継続したまま A[i]を採用しない
          dp[i+1][j][FINISH]+=dp[i][j][ON];//継続が終わる
        }

        {
          dp[i+1][j][FINISH]+=dp[i][j][FINISH];//終わりが終わりのまま
        }
      } 
    }
    dp[N][S][FINISH]+=dp[N][S][ON];//右端がまだ閉じてないものを全て終わらせる
    
    mint ans=dp[N][S][FINISH];

    

    cout<<ans<<endl;
}

Submission Info

Submission Time
Task F - Knapsack for All Segments
User HIcoder
Language C++ 20 (gcc 12.2)
Score 600
Code Size 3289 Byte
Status AC
Exec Time 134 ms
Memory 285856 KiB

Judge Result

Set Name sample All
Score / Max Score 0 / 0 600 / 600
Status
AC × 3
AC × 23
Set Name Test Cases
sample sample01, sample02, sample03
All 11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45, sample01, sample02, sample03
Case Name Status Exec Time Memory
11 AC 95 ms 285652 KiB
12 AC 97 ms 285700 KiB
13 AC 96 ms 285652 KiB
14 AC 97 ms 285652 KiB
15 AC 96 ms 285724 KiB
21 AC 98 ms 285664 KiB
22 AC 112 ms 285656 KiB
23 AC 108 ms 285856 KiB
24 AC 113 ms 285644 KiB
25 AC 100 ms 285784 KiB
31 AC 110 ms 285656 KiB
32 AC 114 ms 285664 KiB
33 AC 113 ms 285660 KiB
34 AC 113 ms 285668 KiB
35 AC 114 ms 285648 KiB
41 AC 134 ms 285848 KiB
42 AC 133 ms 285704 KiB
43 AC 133 ms 285660 KiB
44 AC 134 ms 285704 KiB
45 AC 133 ms 285636 KiB
sample01 AC 95 ms 285648 KiB
sample02 AC 95 ms 285692 KiB
sample03 AC 95 ms 285656 KiB