結果
| 問題 | No.2866 yuusaan's Knapsack | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2025-01-20 21:04:39 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 129 ms / 2,000 ms | 
| コード長 | 4,597 bytes | 
| コンパイル時間 | 933 ms | 
| コンパイル使用メモリ | 82,432 KB | 
| 実行使用メモリ | 76,800 KB | 
| 最終ジャッジ日時 | 2025-01-20 21:04:47 | 
| 合計ジャッジ時間 | 5,874 ms | 
| ジャッジサーバーID (参考情報) | judge1 / judge3 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 26 | 
ソースコード
# input
import sys
input = sys.stdin.readline
II = lambda : int(input())
MI = lambda : map(int, input().split())
LI = lambda : list(map(int, input().split()))
SI = lambda : input().rstrip()
LLI = lambda n : [list(map(int, input().split())) for _ in range(n)]
LSI = lambda n : [input().rstrip() for _ in range(n)]
MI_1 = lambda : map(lambda x:int(x)-1, input().split())
LI_1 = lambda : list(map(lambda x:int(x)-1, input().split()))
def graph(n:int, m:int, dir:bool=False, index:int=-1):
    edge = [set() for i in range(n+1+index)]
    for _ in range(m):
        a,b = map(int, input().split())
        a += index
        b += index
        edge[a].add(b)
        if not dir:
            edge[b].add(a)
    return edge
def graph_w(n:int, m:int, dir:bool=False, index:int=-1):
    edge = [set() for i in range(n+1+index)]
    for _ in range(m):
        a,b,c = map(int, input().split())
        a += index
        b += index
        edge[a].add((b,c))
        if not dir:
            edge[b].add((a,c))
    return edge
mod, inf = 998244353, 1001001001001001001
ordalp = lambda s : ord(s)-65 if s.isupper() else ord(s)-97
ordallalp = lambda s : ord(s)-39 if s.isupper() else ord(s)-97
yes = lambda : print("Yes")
no = lambda : print("No")
yn = lambda flag : print("Yes" if flag else "No")
def acc(a:list[int]):
    sa = [0]*(len(a)+1)
    for i in range(len(a)):
        sa[i+1] = a[i] + sa[i]
    return sa
prinf = lambda ans : print(ans if ans < 1000001001001001001 else -1)
alplow = "abcdefghijklmnopqrstuvwxyz"
alpup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alpall = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
URDL = {'U':(-1,0), 'R':(0,1), 'D':(1,0), 'L':(0,-1)}
DIR_4 = [[-1,0],[0,1],[1,0],[0,-1]]
DIR_8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
DIR_BISHOP = [[-1,1],[1,1],[1,-1],[-1,-1]]
prime60 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59]
# sys.setrecursionlimit(10**5)
# sys.set_int_max_str_digits(0)
class dsu():
    n=1
    parent_or_size=[-1 for i in range(n)]
    def __init__(self,N):
        self.n=N
        self.parent_or_size=[-1 for i in range(N)]
    def merge(self,a,b):
        assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
        assert 0<=b<self.n, "0<=b<n,b={0},n={1}".format(b,self.n)
        x=self.leader(a)
        y=self.leader(b)
        if x==y:
            return x
        if (-self.parent_or_size[x]<-self.parent_or_size[y]):
            x,y=y,x
        self.parent_or_size[x]+=self.parent_or_size[y]
        self.parent_or_size[y]=x
        return x
    def same(self,a,b):
        assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
        assert 0<=b<self.n, "0<=b<n,b={0},n={1}".format(b,self.n)
        return self.leader(a)==self.leader(b)
    def leader(self,a):
        assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
        if (self.parent_or_size[a]<0):
            return a
        self.parent_or_size[a]=self.leader(self.parent_or_size[a])
        return self.parent_or_size[a]
    def size(self,a):
        assert 0<=a<self.n, "0<=a<n,a={0},n={1}".format(a,self.n)
        return -self.parent_or_size[self.leader(a)]
    def groups(self):
        leader_buf=[0 for i in range(self.n)]
        group_size=[0 for i in range(self.n)]
        for i in range(self.n):
            leader_buf[i]=self.leader(i)
            group_size[leader_buf[i]]+=1
        result=[[] for i in range(self.n)]
        for i in range(self.n):
            result[leader_buf[i]].append(i)
        result2=[]
        for i in range(self.n):
            if len(result[i])>0:
                result2.append(result[i])
        return result2
n,sw = MI()
const = 20010
dp = [-inf]*const
cnt = [0]*const
dp[0] = 0
cnt[0] = 1
posi = []
nega = []
for i in range(n):
    v,w = MI()
    if w >= 0:
        posi.append((v,w))
    else:
        nega.append((v,w))
for v,w in nega:
    for j in range(-10000,1):
        if -10000 <= j+w:
            if dp[j] == -inf: continue
            if dp[j+w] < dp[j]+v:
                dp[j+w] = dp[j]+v
                cnt[j+w] = cnt[j]%mod
            elif dp[j+w] == dp[j]+v:
                cnt[j+w] += cnt[j]%mod
for v,w in posi:
    for j in range(-10000,sw+1)[::-1]:
        if -10000 <= j+w <= sw:
            if dp[j] == -inf: continue
            if dp[j+w] < dp[j]+v:
                dp[j+w] = dp[j]+v
                cnt[j+w] = cnt[j]%mod
            elif dp[j+w] == dp[j]+v:
                cnt[j+w] += cnt[j]%mod
ans = max(dp[-10000:] + dp[:sw+1])
ansc = 0
for i in range(-10000, sw+1):
    if dp[i] == ans:
        ansc += cnt[i]
        ansc %= mod
print(ans,ansc)
            
            
            
        