Problem:
 Score : 100 points    Problem Statement There are N items, numbered 1, 2, \ldots, N .
For each i ( 1 \leq i \leq N ), Item i has a weight of w_i and a value of v_i .  Taro has decided to choose some of the N items and carry them home in a knapsack.
The capacity of the knapsack is W , which means that the sum of the weights of items taken must be at most W .  Find the maximum possible sum of the values of items that Taro takes home.      Constraints  All values in input are integers.  1 \leq N \leq 100  1 \leq W \leq 10^5  1 \leq w_i \leq W  1 \leq v_i \leq 10^9         Input Input is given from Standard Input in the following format:  N  W  w_1  v_1  w_2  v_2  :  w_N  v_N       Output Print the maximum possible sum of the values of items that Taro takes home.        Sample Input 1 3 8
3 30
4 50
5 60      Sample Output 1 90  Items 1 and 3 should be taken.
Then, the sum of the weights is 3 + 5 = 8 , and the sum of the values is 30 + 60 = 90 .       Sample Input 2 5 5
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000      Sample Output 2 5000000000  The answer may not fit into a 32-bit integer type.       Sample Input 3 6 15
6 5
5 6
6 4
6 6
3 5
7 2      Sample Output 3 17  Items 2, 4 and 5 should be taken.
Then, the sum of the weights is 5 + 6 + 3 = 14 , and the sum of the values is 6 + 6 + 5 = 17 .

Solution (Python):
N, W = map(int, input().split())
w = [0] * N
v = [0] * N
for i in range(N):
    w[i], v[i] = map(int, input().split())

dp = [[0] * (W+1) for _ in range(N+1)]

for i in range(N):
    for sum_w in range(W+1):
        dp[i+1][sum_w] = max(dp[i+1][sum_w], dp[i][sum_w])
        if sum_w + w[i] > W:
            continue
        dp[i+1][sum_w+w[i]] = max(dp[i+1][sum_w+w[i]], dp[i][sum_w] + v[i])

print(max(dp[N]))

Solution (Python):

import sys
input = sys.stdin.readline

def main():
    N, W = tuple(map(int, input().rstrip().split()))
    A = tuple(tuple(map(int, input().rstrip().split())) for _ in range(N))
    dp = [0] * (W + 1)
    for i in range(N):
        for j in range(W, A[i][0] - 1, -1):
            dp[j] = max(dp[j], dp[j - A[i][0]] + A[i][1])
    print(dp[-1])


if __name__ == "__main__":
    main()

Solution (Python):
n, w = map(int, input().split())
wv = [list(map(int, input().split())) for i in range(n)]

dp = [[0] * (w+1) for i in range(n)]

for i in range(n):
    for j in range(w+1):
        if j < wv[i][0]:
            dp[i][j] = dp[i-1][j]
        else:
            dp[i][j] = max(dp[i-1][j], dp[i-1][j-wv[i][0]] + wv[i][1])

print(dp[-1][-1])

Solution (Python):
import numpy as np
N, W = map(int, input().split())
ndp = np.zeros(W+1, dtype= np.int64)
for _ in range(N):
    w, v = map(int,input().split())

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np
N, W = map(int, input().split())
ndp = np.zeros(W+1, dtype= np.int64)
for _ in range(N):
    w, v = map(int,input().split())
    """
    
集合
ナビゲーションに移動検索に移動
曖昧さ回避	この項目では、数学における集合について説明しています。クルアーンのスーラについては「集合 (クルアーン)」をご覧ください。
数学における集合 (しゅうごう、英: set, 仏: ensemble, 独: Menge) とは、大雑把に言えばいくつかの「もの」からなる「集まり」である。集合を構成する個々の「もの」のことを元 (げん、英: element; 要素) という。

集合は、集合論のみならず現代数学全体における最も基本的な概念の一つであり、現代数学のほとんどが集合と写像の言葉で書かれていると言ってよい。

慣例的に、ある種の集合が系 (けい、英: system) や族 (ぞく、英: family) などと呼ばれることもある。実際には、これらの呼び名に本質的な違いはないが細かなニュアンスの違いを含むと考えられている。たとえば、方程式系（「相互に連立する」方程式の集合）、集合族（「一定の規則に基づく」集合の集合）、加法族（「加法的な性質を持つ」集合族）など。


目次
1導入
2帰属と包含
3記法
4外延性の公理
5特別な集合
6濃度
7集合の演算
7.1基本的な集合演算
7.2その他の演算
7.3いくつかの集合族
8注記
9関連項目
10外部リンク
導入
集合は「もの」の「集まり」である。集合の元（要素）として集められる対象となる「もの」は、数、文字、記号などをはじめ、どんなものでも（もちろん集合でも）構わない。

一方で、どんな「集まり」でも集合と呼んでよいわけではない。その「集まり」が集合と呼ばれるためには、対象が「その集まりの元であるかどうかが不確定要素なしに一意に決定できる」ように定義されていなければならない。

たとえば、トランプのスート全体 {♠, ♦, ♣, ♥} やトランプの数字全体 {A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K} は集合の例である。トランプは（ジョーカーを除いて）これらの組

{(♠,A), ..., (♠,K), (♦,A), ..., (♦,K), (♣,A), ..., (♣,K), (♥,A), ..., (♥,K)}
を符牒とする52枚のカードであるが、これもまた集合の一例になっている。とくにこれはスートの集合と数字の集合との直積集合の例であり、また 52 というのはこの集合の濃度を表している。また、先のスートの集合、数字の集合の濃度はそれぞれ 4, 13 である。

トランプの記号
A	2	3	4	5	6	7	8	9	10	J	Q	K
♠	(♠,A)	(♠,2)	(♠,3)	(♠,4)	(♠,5)	(♠,6)	(♠,7)	(♠,8)	(♠,9)	(♠,10)	(♠,J)	(♠,Q)	(♠,K)
♦	(♦,A)	(♦,2)	(♦,3)	(♦,4)	(♦,5)	(♦,6)	(♦,7)	(♦,8)	(♦,9)	(♦,10)	(♦,J)	(♦,Q)	(♦,K)
♣	(♣,A)	(♣,2)	(♣,3)	(♣,4)	(♣,5)	(♣,6)	(♣,7)	(♣,8)	(♣,9)	(♣,10)	(♣,J)	(♣,Q)	(♣,K)
♥	(♥,A)	(♥,2)	(♥,3)	(♥,4)	(♥,5)	(♥,6)	(♥,7)	(♥,8)	(♥,9)	(♥,10)	(♥,J)	(♥,Q)	(♥,K)
集合を表すプレースホルダにはしばしばラテン文字の大文字 A, B, ..., E, F, ..., M, N, ..., S, T, ..., X, Y, ... など[1]を使い、集合の元は（とくに集合を表すのに使った文字に対応する）ラテン小文字 a, ..., e, ..., m, ..., s, ..., x, ... とすることが多い[2]。

帰属と包含
詳細は「部分集合」、「包含関係」、「元 (数学)」、および「帰属関係」を参照

包含関係: A は B の部分である。B は A の上にある。
集合と元、集合と集合などの間には含んだり含まれたりといった素朴な関係を考えることができる。

帰属関係
対象 a が集合 A を構成するものの一つであるとき、「a は集合 A に属す」「a は集合 A の要素（あるいは元）である」「集合 A は a を要素として持つ」などといい、a ∈ A あるいは A ∋ a と表す。
包含関係
2 つの集合 A, B について、A に属する元がすべて B にも属するとき、すなわち x ∈ A ⇒ x ∈ B が a の取り方に依らずに成り立つとき、「A は B の部分集合である」「A は B に集合として含まれる」「B は A を包含する」などといい、A ⊂ B または A ⊆ B あるいは B ⊃ A または B ⊇ A と記す。
帰属関係と包含関係は異なる概念であって、混同してはならない。例えば、X ⊂ Y ⊂ Z ならば必ず X ⊂ Z であるが、X ∈ Y ∈ Z からは X ∈ Z は必ずしも導かれない。また、x ∈ A ⊂ B ならば x ∈ B であるが、x ⊂ A ∈ B からは x ∈ B を帰結することは一般にはできない。

記法
集合の記法には、おおまかに2通りの方法がある。論理的な概念として「外延と内包」というものがあるが、ほぼそれに相当するもので、その要素をすべて列挙するという方法と、その集合に含まれるのであれば必ず満たされ、含まれないのであれば必ず満たされない条件を明示するという方法である。

「外延」に相当する、すべて列挙する方法では、例えば、1, 3, 5, 7, 9 からなる集合は、

{\displaystyle \{1,3,5,7,9\}} \{1, 3, 5, 7, 9\}
と表記する。

「内包」に相当する、属するために満たすべき条件を明示する方法では、例えば、10 未満の正の奇数全体の集合を、

{ x | x は 10 未満の正の奇数 }
と表記する。一般に、条件 P(x) があったとき、それをみたす対象だけを全て集めた集合を、

{\displaystyle \{x\mid P(x)\}} \{x \mid P(x)\}
と表記する。ここでは x という変数を用いているが、{ y | P(y) } と書いても { a | P(a) } と書いても構わない。set-builder notation（en:Set-builder notation）やset comprehension、日本語では内包表記などとも言う。前述のようにそれぞれ、論理的な概念の外延と内包に由来するものであり日本語圏では数学分野でも今もそれらの語がよく使われているが、英語圏ではそれぞれの原語であるextensionとintensionはこの分野では今はあまり見なくなっている。

条件 P(x) は「x が X の元であって、さらに条件 Q(x) を満たす」というような形で与えられることが多い[3]が、このとき定まる集合を {x | x ∈ X かつ Q(x)} のように書く代わりに、しばしば簡単に

{\displaystyle \{x\in X\mid Q(x)\}} \{x \in X \mid Q(x)\}
などと略記する。集合 {x ∈ X | Q(x)} は X の部分集合となる。また、条件 P(x) が「条件 Q(y) を満たすようなある y を用いて x = f(y) と表すことができる」というような形のときは、集合 { x | P(x) } を

{\displaystyle \{f(y)\mid Q(y)\}} \{f(y) \mid Q(y)\}
のように表すこともある。

要素を外延的に書きつくせないような集合、例えば自然数全体の集合を

{\displaystyle \{0,1,2,3,\dots \}} \{0, 1, 2, 3, \dots \}
のように書き表すこともあるが、"..." による省略部分は誤解を生じる余地があるため、このような記法はその省略された内容の意味が明らかである場合に限られる。

外延性の公理
A, Bを任意の集合とするとき、もし任意の集合Xについて「XがAの要素であるならば、そのときに限りXはBの要素である」が成り立つならば、AとBは等しい、とする。すなわち、

{\displaystyle \forall A\,\forall B\,(\forall X\,(X\in A\iff X\in B)\Rightarrow A=B)} \forall A\,\forall B\,(\forall X\,(X\in A\iff X\in B)\Rightarrow A=B)
である。

「外延性の公理」を参照
直感的な説明としては、たとえば、{1, 3, 5, 7, 9} と { x | x は 10 未満の正の奇数 } は異なる表現だが、どちらも自然数 1, 3, 5, 7, 9 を要素とする集合であるので、等しい集合だとする、ということである。

特別な集合
数学では、1 つも要素を持たないような集合も考える。外延性の原理によれば、このような集合はただ一つしか存在しないので、これを空集合 (英: empty set) といい ∅ で表す。∅ は任意の集合 A の部分集合である。なぜなら、任意の対象 x に対して x ∉ ∅ より x ∈ ∅ ⇒ x ∈ A は真だからである。空集合の他にも決まった記号によって表される集合がいくつかある：

{\displaystyle \mathbb {N} } \mathbb{N} は自然数全体の集合を表す。
{\displaystyle \mathbb {Z} } \mathbb{Z} は整数全体の集合を表す。
{\displaystyle \mathbb {Q} } \mathbb{Q} は有理数全体の集合を表す。
{\displaystyle \mathbb {R} } \mathbb{R} は実数全体の集合を表す。
{\displaystyle \mathbb {C} } \mathbb{C} は複素数全体の集合を表す。
{\displaystyle \mathbb {H} } \mathbb{H} は四元数全体の集合を表す。
{\displaystyle \mathbb {U} } \mathbb{U} はグロタンディーク宇宙を表す。
濃度
詳細は「濃度 (数学)」を参照
有限個の元からなる集合を有限集合 (ゆうげんしゅうごう、英: finite set) と呼び、集合 A の元の個数を 

無限集合はどれも「無限個」の元を持っているわけだが、どの無限もみな同じというわけではなく、濃度の概念ではたくさんの無限を区別して扱うことになる。たとえば、自然数と有理数が同じ濃度を持つ、自然数と実数は真に異なる濃度を持つといったような事実は数学を学ぶ者にとってよく知られた内容である。同様の事実に、平面 R2 と数直線 R は同じ濃度を持ち、平面を覆いつくす平面充填曲線と呼ばれる不思議な平面曲線が何種類も存在することが述べられる。より次元の高い空間でも同様で、空間を埋め尽くす空間充填曲線が構築される。異なる次元をもつ空間が同じ濃度をもつというのは、次元や濃度が一方が他方を測るようなものではない異なる尺度であることを表しているのである。

集合の演算
いくつかの集合を扱い、その関係性について論じるとき、もともと考えていた集合たちから新しい集合を作って調べるというのは有効な手段の一つである。これらの操作は、集合に対する演算と見なすことによって、集合族に関するいくつかの代数系を提供する。それらの代数系を抽象代数系と見なせば、抽象代数学の一般論を適用することでまたいくつかの概念を提供することになる。

基本的な集合演算
結び・合併・和
詳細は「合併 (集合論)」を参照

結びの模式図
二つの集合を「くっつけ」て一緒にしてしまうことで新しい集合を取り出すことができる。加法的な集合族の基本となる演算のひとつ。和集合。
{\displaystyle A\cup B:=\{x\mid x\in A\lor x\in B\}.} {\displaystyle A\cup B:=\{x\mid x\in A\lor x\in B\}.}
交わり・交叉・積
詳細は「交叉 (集合論)」を参照

交わりの模式図
二つの集合の共通した部分を見つけることで、新しい集合を取り出すことができる。乗法的な集合族の基本となる演算。共通部分。
{\displaystyle A\cap B:=\{x\mid x\in A\land x\in B\}.} {\displaystyle A\cap B:=\{x\mid x\in A\land x\in B\}.}
差・相対補
詳細は「差集合」を参照

差集合の模式図
二つの集合のうちの一方の集合について、それに帰属する元のうち、同時に他方にも含まれる元を取り除いて新しい集合を作ることができる。差は一方と他方の補集合との交わりであり、乗法的な演算である。
{\displaystyle A\smallsetminus B:=\{x\mid x\in A\land x\notin B\}.} {\displaystyle A\smallsetminus B:=\{x\mid x\in A\land x\notin B\}.}
補・絶対補
詳細は「差集合」を参照

補集合の模式図
全体集合（普遍集合）が与えられ、任意の集合は全体集合の部分集合であるという仮定のもとで、一つの集合の全体からの差。勝手な集合はその補集合と交わりを持たず、それらの和は全体集合に一致する。
{\displaystyle \complement A:=\{x\mid x\notin A\}.} \complement A := \{x\mid x\notin A\}.
対称差
詳細は「対称差」を参照

対称差の模式図
二つの集合の結びに帰属する元から、その交わりに属する元を取り除いて新しい集合を考えることができる。これは結びから交わりを引いた差である。結びと同様に加法的な演算。
{\displaystyle A\,\triangle \,B:=(A\smallsetminus B)\cup (B\smallsetminus A).} A\,\triangle\,B := (A\smallsetminus B)\cup(B\smallsetminus A).
指示関数はこれらの集合演算を 0 と 1 からなる世界の代数的な演算に置き換える手段を与える。

{\displaystyle A\leftrightarrow \mathbf {1} _{A}(x):={\begin{cases}1&(x\in A)\\0&(x\notin A)\end{cases}}.} A \harr \mathbf{1}_A(x):=\begin{cases}1&(x\in A)\\0&(x\notin A)\end{cases}.
その他の演算
上記演算は、全体集合が一つ与えられ、演算の引数となる集合たちがその部分集合であるならば、その演算結果もふたたび同じ全体集合の部分集合となるようなものである。一方、もとの全体集合の中に演算結果を求めるのではなく、むしろ引数となる集合たちをもとに新しい集合を作り出すことを目的とする演算もある。

冪
詳細は「冪集合」を参照

三元集合の冪の模式図
与えられた集合に対して、その冪集合とは与えられた集合に包含される集合全体の集合である。ある集合の冪集合はその集合の部分集合からなる集合族のなかで最大のものであると言っても同じである。
{\displaystyle {\mathcal {P}}(X):=\{S\mid S\subseteq X\}.} \mathcal{P}(X) := \{S\mid S\subseteq X\}. 
直積
詳細は「直積集合」を参照

直積の模式図
二つの集合に対し、それぞれに帰属する元の順序付けられた対を要素とする集合を作ることができる。
{\displaystyle X\times Y:=\{(x,y)\mid x\in X\land y\in Y\}.} {\displaystyle X\times Y:=\{(x,y)\mid x\in X\land y\in Y\}.}
直和・非交和
詳細は「非交和」を参照
二つの集合の、交わりを持たない和。
配置集合・写像空間
詳細は「配置集合」を参照
ある集合から別の集合への写像を一つの元と見なすならば、その全体として新たな集合が見出される。直積集合は、順序数の各元に任意の集合を対応させる写像からなる配置集合と見ることもできる。
{\displaystyle Y^{X}:=\{f\mid f{\text{ is a mapping from }}X{\text{ to }}Y\}.} Y^X := \{f\mid f\text{ is a mapping from }X\text{ to }Y \}.
商
詳細は「商集合」を参照

集合の類別の模式図
集合に類別を与えるとき、各類をその要素とする集合を考えることができる。
{\displaystyle X/{\sim }{}:=\{[x]\mid x\in X\},{\text{ where }}[x]:=\{y\in X\mid y\sim x\}.} X/{\sim} {}:= \{[x]\mid x\in X\}, \text{ where } [x] := \{y\in X\mid y\sim x\}.
いくつかの集合族
詳細は「集合の代数学」および「集合族」を参照
集合からなる族 A を考える。A が集合演算についていくつかの性質を満たすとき、それらには特別の名前が与えられることがある。

A が（有限）交叉について閉じているとき π-系（英語版）であるといい、π-系が空集合を含むとき乗法族である[4]という[5]（ディンキン族も参照）。さらに可算交叉について閉じているとき δ-乗法族であるという。また、乗法族が包含関係を持つ任意の二つの集合に対し、一方から有限回の非交和を行って他方へ達する列を持つとき集合半環という。
A が（有限）和と（有限）交叉について閉じているとき、集合の束あるいは環という。A が空集合でなく（あるいは空集合を元として含み）、和と差について閉じている（あるいは同じことだが対称差と交叉について閉じている）場合に限って集合環と呼ぶ場合もある。さらに可算交叉について閉じていれば δ-集合環、可算和について閉じていれば σ-集合環という。また、これらが全体集合を含むならば代数あるいは体という。δ-集合体は σ-集合体である。
A が空集合を含み、（有限）和および補について閉じているとき加法族、特に有限加法族であるという。さらに可算和について閉じているならば完全加法族という。集合族 A が加法族であることは集合体であることと等価であり、同様に完全加法族は σ-集合体の別名である。
単調族は包含関係に関する単調列の極限について閉じている集合族
ディンキン族（d-族、δ-族）は全体集合を含み、包含関係を持つ集合同士の差について閉じていて、可算増大列の極限について閉じている。λ-系は全体集合を含み、補について閉じていて、可算非交和について閉じている。この二つは同じ概念を定める。
層族はそれに属する任意の集合 A, B が A ⊂ B または A ⊃ B または A ∩ B ≠ ∅ の何れか一つのみを満たす。
ブール環
注記
定数や変数に対する慣例を踏襲して A, B, ... や X, Y, ... が使われるほか、英語の set, ドイツ語の Menge, フランス語の ensemble の頭文字 S, M, E やその周辺の文字がよく使われる。
ラテンアルファベット以外にもギリシャ文字を使うこともある。集合の集合を考えるときは、元である集合に大文字を使うことから、筆記体 {\displaystyle \scriptstyle {\mathcal {A,\ldots ,E,\ldots ,M,\ldots ,S,\ldots ,X,\ldots }}} \scriptstyle \mathcal{A,\ldots, E,\ldots, M,\ldots, S,\ldots, X,\ldots}やドイツ文字 {\displaystyle \scriptstyle {\mathfrak {A,\ldots ,M,\ldots ,X,\ldots }}} \scriptstyle \mathfrak{A,\ldots, M,\ldots, X,\ldots}で記したりする。このような入れ子構造は何重にも複雑な形で現われたり、同じものが違った見方をされたりするので、このような文字種の変更を行わないこともよくある。
「x が X の元であって」というような断り書きをしない場合にも、実際には「普遍集合」 (英: universal set) あるいは「宇宙」 (英: universe) と呼ばれる、必要な議論を展開することができる程度に十分大きな集合を考え、集合と言えば必ずその普遍集合の部分集合だけを考えているといったようなことがしばしば行われる。条件 P(x) の形から x の属するべき集合 X がある程度限定される場合にも、断り書きはしばしば省略される。
例えば定義 2.1.
しばしば π-系と乗法族はこれと逆に扱われたり同義語の場合もある。例えば定義 1.3.6.や[1]は乗法族 (multiplicative class) に交叉について閉じていることのみを課している。
関連項目
ウィクショナリーに集合の項目があります。
写像
集合論 - 素朴集合論/公理的集合論
定義 - 外延と内包
セット (抽象データ型) - コンピュータ上での実装
外部リンク
Hazewinkel, Michiel, ed. (2001), "Set", Encyclopaedia of Mathematics, Springer, ISBN 978-1-55608-010-4
Weisstein, Eric W. "Set". MathWorld（英語）.
set - PlanetMath.（英語）
Sets in nLab
[隠す]
表話編歴
集合論
公理	
外延性の公理 空集合の公理 分出公理（英語版） 対の公理 和集合公理 冪集合公理 置換公理（英語版） 無限公理 正則性公理 選択公理
演算	
和集合 共通部分 直積集合 商集合 補集合 差集合 対称差 冪集合
概念	
濃度 基数 順序数 クラス 元 1対1の対応 ベン図
集合	
空集合 有限集合 可算集合 無限集合 部分集合
理論	
カントールの定理 素朴集合論（英語版） 公理的集合論 パラドックス ラッセルのパラドックス
人々	
ゲオルク・カントール バートランド・ラッセル エルンスト・ツェルメロ アドルフ・フレンケル
典拠管理	
GND: 4038613-2
カテゴリ: 集合論初等数学数学的対象数学に関する記事
案内メニュー
ログインしていませんトーク投稿記録アカウント作成ログインページノート閲覧編集履歴表示検索
Wikipedia内を検索
メインページ
コミュニティ・ポータル
最近の出来事
新しいページ
最近の更新
おまかせ表示
練習用ページ
アップロード (ウィキメディア・コモンズ)
ヘルプ
ヘルプ
井戸端
お知らせ
バグの報告
寄付
ウィキペディアに関するお問い合わせ
ツール
リンク元
関連ページの更新状況
ファイルをアップロード
特別ページ
この版への固定リンク
ページ情報
ウィキデータ項目
このページを引用
他のプロジェクト
コモンズ
印刷/書き出し
ブックの新規作成
PDF 形式でダウンロード
印刷用バージョン
他言語版
Deutsch
English
Español
Français
हिन्दी
한국어
Português
اردو
中文
他 84
リンクを編集
最終更新 2019年1月12日 (土) 11:45 （日時は個人設定で未設定ならばUTC）。
テキストはクリエイティブ・コモンズ 表示-継承ライセンスの下で利用可能です。追加の条件が適用される場合があります。詳細は利用規約を参照してください。
プライバシー・ポリシーウィキペディアについて免責事項開発者Cookieに関する声明モバイルビューWikimedia Foundation Powered by MediaWiki

    """
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np
N, W = map(int, input().split())
ndp = np.zeros(W+1, dtype= np.int64)
for _ in range(N):
    w, v = map(int,input().split())
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np
N, W = map(int, input().split())
ndp = np.zeros(W+1, dtype= np.int64)
for _ in range(N):
    w, v = map(int,input().split())

    
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np
N,W = map(int,input().split())
ndp = np.zeros(W+1,dtype= np.int64)
for _ in range(N):
    w,v = map(int,input().split())
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np
N, W = map(int, input().split())
ndp = np.zeros(W+1, dtype= np.int64)
for _ in range(N):
    w, v = map(int,input().split())

    
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])


"""
https://atcoder.jp/contests/dp/submissions/6657472
より失敬。

めっちゃスマートな解法。
"""

Solution (Python):

import sys
input = sys.stdin.readline

def main():
    n, w = tuple(map(int, input().rstrip().split()))
    A = tuple(tuple(map(int, input().rstrip().split())) for _ in range(n))
    dp = [[0] * (w + 1) for i in range(n)]
    for i in range(n):
        for j in range(w + 1):
            if j < A[i][0]:
                dp[i][j] = dp[i - 1][j]
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - A[i][0]] + A[i][1])
    print(max(dp[-1]))


if __name__ == "__main__":
    main()

Solution (Python):


import sys
input = sys.stdin.readline

def main():
    n, w = tuple(map(int, input().rstrip().split()))
    A = tuple(tuple(map(int, input().rstrip().split())) for _ in range(n))
    dp = [0] * (w + 1)
    for i in range(n):
        for j in range(w, A[i][0] - 1, -1):
            dp[j] = max(dp[j], dp[j - A[i][0]] + A[i][1])
    print(max(dp))
    


if __name__ == "__main__":
    main()

Solution (Python):
def main():
  n, w = [int(e) for e in input().split()]
  t = [-1 for i in range(w + 1)]
  t[w] = 0
  for _ in range(n):
    nw, nv = [int(e) for e in input().split()]
    for i in range(nw, w + 1):
      if t[i] == -1:
        continue
      if t[i - nw] < t[i] + nv:
        t[i - nw] = t[i] + nv
  print(max(t))
main()

Solution (Python):
def main():
  n, w = [int(e) for e in input().split()]
  t = [-1 for i in range(w + 1)]
  t[w] = 0
  for _ in range(n):
    nw, nv = [int(e) for e in input().split()]
    for i in range(nw, w + 1):
      if t[i] == -1:
        continue
      if t[i - nw] < t[i] + nv:
        t[i - nw] = t[i] + nv
  print(max(t))
main()

Solution (Python):
from functools import cmp_to_key
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
d.sort(key = cmp_to_key(lambda x, y: y[1] / y[0] - x[1] / x[0]))
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys())) 
  tw, tv = d[i]
  updates = []
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw not in t or nv > t[nw]:
      updates.append([nw, nv])
  for u in updates:
    t[u[0]] = u[1]
print(max(t.values()))

Solution (Python):
from functools import cmp_to_key
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
d.sort(key = cmp_to_key(lambda x, y: x[1] / x[0] - y[1] / y[0]))
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys())) 
  tw, tv = d[i]
  updates = []
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw not in t or nv > t[nw]:
      updates.append([nw, nv])
  for u in updates:
    t[u[0]] = u[1]
print(max(t.values()))

Solution (Python):
from functools import cmp_to_key
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
d.sort(key = cmp_to_key(lambda x, y: x[1] / x[0] - y[1] / y[0]))
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys())) 
  tw, tv = d[i]
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw not in t or nv > t[nw]:
      t[nw] = nv
print(max(t.values()))

Solution (Python):
from functools import cmp_to_key
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
d.sort(key = cmp_to_key(lambda x, y: y[1] / y[0] - x[1] / x[0]))
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys())) 
  tw, tv = d[i]
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw in t:
      if nv > t[nw]:
        for k in list(t.keys()):
          if k <= nw and t[k] < nv:
            del t[k]
        t[nw] = nv
    else:
      Flag = False
      for k in t:
        if nw <= k and nv <= t[k]:
          Flag = True
          break
      if Flag:
        continue
      for k in list(t.keys()):
        if k <= nw and t[k] < nv:
          del t[k]
      t[nw] = nv
        
print(max(t.values()))

Solution (Python):
n, w = [ int(v) for v in input().split() ]
value_list = [ [ 0 for i in range(w+1) ] for j in range(n+1) ]
for i in range(1,n+1):
    a, b = [ int(v) for v in input().split() ]
    for j in range(a):
        value_list[i][j] = value_list[i-1][j]
    for j in range(a,w+1):
        value_list[i][j] = max(value_list[i-1][j],value_list[i-1][j-a]+b)

print(value_list[-1][-1])

Solution (Python):
N, W = map(int, input().split())
wv = [tuple(map(int, input().split())) for _ in range(N)]

dp = [[0 for _ in range(W+1)] for _ in range(N)]

for i in range(N):
    for j in range(W+1):
        if j >= wv[i][0]:
            dp[i][j] = max(dp[i-1][j], dp[i-1][j-wv[i][0]] + wv[i][1])
        else:
            dp[i][j] = dp[i-1][j]

print(dp[N-1][W])

Solution (Python):
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys())) 
  tw, tv = d[i]
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw in t:
      if nv > t[nw]:
        t[nw] = nv
    else:
      t[nw] = nv
print(max(t.values()))

Solution (Python):
n, w = [int(e) for e in input().split()]
d = [[int(e) for e in input().split()] for i in range(n)]
t = {}
t[w] = 0
for i in range(n):
  keys = list(sorted(t.keys()))
  tw, tv = d[i]
  for j in keys:
    nw = j - tw
    if nw < 0:
      continue
    nv = t[j] + tv
    if nw in t:
      if nv > t[nw]:
        t[nw] = nv
    else:
      t[nw] = nv
print(max(t.values()))

Solution (Python):
N, W = map(int, input().split(" "))
WV = [list(map(int, input().split(" "))) for _ in range(N)]

dp = [[0 for _ in range(W+1)] for _ in range(N+1)]

for i, (w, v) in enumerate(WV):
    for j in range(W+1):
        if w <= j:
            dp[i+1][j] = max(
                dp[i][j-w] + v,
                dp[i][j]
            )
        else:
            dp[i+1][j] = dp[i][j]

print(dp[N][W])

Solution (Python):
import numpy as np
N,W = map(int,input().split())
ndp = np.zeros(W+1,dtype= np.int64)
for _ in range(N):
    w,v = map(int,input().split())
    np.maximum(ndp[:-w] + v, ndp[w:], out = ndp[w:])
print(ndp[-1])

Solution (Python):
import numpy as np

n, ww = map(int, input().split())

s = np.zeros(ww+1, dtype=np.int64)
for i in range(n):
    w, v = map(int, input().split())
    s[w:] = np.maximum(s[w:], s[:-w] + v)

print(s[ww])

Solution (Python):
n, w = [int(i) for i in input().split()]

sv = {}
for i in range(n):
    ww, vv = map(int, input().split())
    if ww > w:
        continue
    added = {}
    for k, v in sv.items():
        if (ww+k) <= w:
            added[ww+k] = vv+v
    for k, v in added.items():
        sv[k] = max(v, sv.get(k, 0))

    sv[ww] = max(vv, sv.get(ww, 0))

print(max(sv.values()))

Solution (Python):
n, w = [int(i) for i in input().split()]
a = [[int(n) for n in input().split()] for i in range(n)]


sv = {}
for ww, vv in a:
    if ww > w:
        continue
    added = {}
    for k, v in sv.items():
        if (ww+k) <= w:
            added[ww+k] = vv+v
    for k, v in added.items():
        sv[k] = max(v, sv.get(k, 0))

    sv[ww] = max(vv, sv.get(ww, 0))

print(max(sv.values()))

Solution (Python):
n, w = [int(i) for i in input().split()]
a = [[int(n) for n in input().split()] for i in range(n)]

sv = {}
for ww, vv in a:
    added = {}
    for k, v in sv.items():
        added[ww+k] = vv+v
    for k, v in added.items():
        if (k <= w) and (k not in sv or v > sv[k]):
            sv[k] = v

    if (ww <= w) and (ww not in sv or vv > sv[ww]):
        sv[ww] = vv

print(max(sv.values()))

Solution (Python):
def solve():
    max_weight, list_of_weight_and_value = read()
    result = think(max_weight, list_of_weight_and_value)
    write(result)
 
 
def read():
    n, max_weight = read_int(2)
    list_of_weight_and_value = []
    for i in range(n):
        list_of_weight_and_value.append(read_int(2))
    return max_weight, list_of_weight_and_value
 
 
def read_int(n):
    return list(map(lambda x: int(x), read_line().split(' ')))[:n]
 
 
def read_line(n=0):
    if n == 0:
        return input().rstrip()
    else:
        return input().rstrip()[:n]
 
 
def think(max_weight, list_of_weight_and_value):
    MAX_WEIGHT = 10 ** 5
    MAX_N = 100
    INVALID_VALUE = MAX_WEIGHT * MAX_N + 1
 
    
    dp = [INVALID_VALUE for x in range(max_weight + len(list_of_weight_and_value) + 1)]
    dp[0] = 0
 
    for weight, value in list_of_weight_and_value:
        for i in range(len(dp) - 1, -1, -1):
            if dp[i] != INVALID_VALUE and i + weight < len(dp):
                if dp[i + weight] == INVALID_VALUE:
                    dp[i + weight] = dp[i] + value
                else:
                    dp[i + weight] = max(dp[i + weight], dp[i] + value)
    return max(filter(lambda x: x != INVALID_VALUE, dp[:max_weight + 1]))
 
 
def write(result):
    print(result)
 
 
if __name__ == '__main__':
    solve()

Solution (Python):
def solve():
    max_weight, list_of_weight_and_value = read()
    result = think(max_weight, list_of_weight_and_value)
    write(result)


def read():
    n, max_weight = read_int(2)
    list_of_weight_and_value = []
    for i in range(n):
        list_of_weight_and_value.append(read_int(2))
    return max_weight, list_of_weight_and_value


def read_int(n):
    return list(map(lambda x: int(x), read_line().split(' ')))[:n]


def read_line(n=0):
    if n == 0:
        return input().rstrip()
    else:
        return input().rstrip()[:n]


def think(max_weight, list_of_weight_and_value):
    MAX_WEIGHT = 10 ** 5
    MAX_N = 100
    INVALID_VALUE = -1

    
    dp = [INVALID_VALUE for x in range(max_weight + len(list_of_weight_and_value) + 1)]
    dp[0] = 0

    for weight, value in list_of_weight_and_value:
        for i in range(len(dp) - 1, -1, -1):
            if dp[i] != INVALID_VALUE and i + weight < len(dp):
                if dp[i + weight] == INVALID_VALUE:
                    dp[i + weight] = dp[i] + value
                else:
                    dp[i + weight] = max(dp[i + weight], dp[i] + value)
    return max(filter(lambda x: x != INVALID_VALUE, dp[:max_weight + 1]))


def write(result):
    print(result)


if __name__ == '__main__':
    solve()

Solution (Python):
import numpy as np 
IN = lambda:map(int, input().split())
 
n, k = IN()
dp = np.zeros(k + 1)
 
for i in range(n):
    w, c = IN()
    dp[w:] = np.maximum(dp[w:], dp[:-w] + c)
    
print(int(dp[-1]))

Solution (Python):
import sys
import numpy as np
input = sys.stdin.readline


def main():
    N, W = map(int, input().split())
    w = np.zeros(N, dtype=int)
    v = np.zeros(N, dtype=int)
    for i in range(N):
        w[i], v[i] = map(int, input().split())

    dp = np.zeros((N+1, W+1), dtype=np.int64)

    for i in range(0, N):
        dp[i+1][:w[i]] = dp[i][:w[i]]
        dp[i+1][w[i]:] = np.maximum(dp[i][w[i]:], dp[i][:-w[i]] + v[i])

    print(dp[N][W])


if __name__ == "__main__":
    main()

Solution (Python):
n,w = map(int,input().split())
wv_list = [map(int,input().split()) for _ in range(n)]
dp = [0]*(w+1)
for ww,vv in wv_list:
    for i in range(w, ww-1, -1):
        t = dp[i-ww] + vv
        dp[i] = max(dp[i], t)
print(max(dp))

Solution (Python):
n,w = map(int,input().split())
wv_list = [map(int,input().split()) for _ in range(n)]
dp = [0]*(w+1)

for ww,vv in wv_list:
    for i in range(w, ww-1, -1):
        t = dp[i-ww] + vv
        if dp[i] < t:
            dp[i] = t
print(max(dp))

Solution (Python):
n, w = map(int, input().split())
item = [list(map(int, input().split())) for i in range(n)]

dp = [[0 for i in range(w + 1)] for j in range(n + 1)]

for i in range(n):
    for sum_w in range(w + 1):
        if sum_w - item[i][0] >= 0:
            dp[i + 1][sum_w] = max(dp[i + 1][sum_w], dp[i][sum_w - item[i][0]] + item[i][1])
        dp[i + 1][sum_w] = max((dp[i + 1][sum_w], dp[i][sum_w]))
print(dp[n][w])

Solution (Python):
N,W=map(int,input().split())
A=[]
for _ in range(N):
    B=list(map(int,input().split()))
    A.append(B)
dp=[]
for _ in range(N):
    dp.append([0]*(W+1))
for j in range(W+1):
    if j>=A[0][0]:
        dp[0][j]=A[0][1]
for i in range(0,N-1):
    for w in range(W+1):
        if w>=A[i+1][0]:
            dp[i+1][w]=max(dp[i][w-A[i+1][0]]+A[i+1][1],dp[i][w])
        else:
            dp[i+1][w]=dp[i][w]
print(dp[N-1][W])

Solution (Python):
N,W = map(int,input().split())
wv = list(list(map(int,input().split()))for i in range(N))
DP = [[0]*(W+1) for i in range(N+1)]

for i in range(1,N+1):
    w,v = wv[i-1]
    for j in range(1,W+1):
        if j >= w:
            DP[i][j] = max(DP[i-1][j],DP[i][j-1],DP[i-1][j-w]+v)
        else:
            DP[i][j] = max(DP[i-1][j],DP[i][j-1])
print(DP[-1][-1])

Solution (Python):

N,W = map(int,input().split())
WV = [list(map(int,input().split())) for i in range(N)]
dp = [[0 for i in range(W+1)] for j in range(N+1)]
for i in range(N):
    w,v = WV[i][0],WV[i][1]
    for j in range(W+1):
        if j >= w:
            dp[i+1][j] = max(dp[i][j-w]+v,dp[i][j])
        else:
            dp[i+1][j] = dp[i][j]
MAX = 0
for i in range(N+1):
    for j in range(W+1):
        MAX = max(MAX,dp[i][j])
print(MAX)

Solution (Python):
n,w = map(int,input().split())
wt = [0]*n
v = [0]*n
dp = [[0 for _ in range(w)]for _ in range(n)]
for i in range(n):
    wt[i],v[i] = map(int,input().split())
for i in range(w):
    if(wt[0]>i+1):dp[0][i] = 0
    else:dp[0][i] = v[0]
for i in range(1,n):
    for j in range(w):
        if(wt[i]>j+1):
            dp[i][j] = dp[i-1][j]
        else:
            remain = (j+1) - wt[i]
            res = 0
            if(remain > 0):
                res = v[i] + dp[i-1][remain-1]
            else:
                res = v[i]
            dp[i][j] = max(dp[i-1][j],res)

print(dp[n-1][w-1])

Solution (Python):
n, w = map(int, input().split())
dp = [[0 for _ in range(w+1)] for _ in range(n+1)]


for i in range(n):
    wi, vi = map(int, input().split())
    sum_w = 0
    while sum_w <= w:
        if sum_w - wi >= 0:
            dp[i+1][sum_w] = max(dp[i+1][sum_w], dp[i][sum_w - wi] + vi)
        dp[i+1][sum_w] = max(dp[i+1][sum_w], dp[i][sum_w])
        sum_w += 1

print(dp[n][w])

Solution (Python):
def number():
    return int(input())


def space():
    return list(map(int, input().split()))


def seq_space(n):
    return [list(map(int, input().split())) for _ in range(n)]


N, W = space()
WV = seq_space(N)

DP = [[0] * (W+1) for _ in range(N+1)]

for i in range(1, N+1):
    w, v = WV[i-1]
    for j in range(W+1):
        if j-w < 0:
            DP[i][j] = DP[i-1][j]
        else:
            DP[i][j] = max(DP[i-1][j-w] + v, DP[i-1][j])

print(max(DP[-1]))

Solution (Python):
import numpy as np

N, W = map(int, input().split())
inputs = np.array([np.array([int(i) for i in input().split()]) for _ in range(N)])

dp = np.zeros(W+1, dtype=np.int64)
for n in range(1, N+1):
    weight, value = inputs[n-1][0], inputs[n-1][1]
    dp[weight:] = np.maximum(dp[weight:], dp[:-weight] + value)

print(dp[-1])

Solution (Python):
N, W = map(int, input().split())
Bs = [tuple(map(int, input().split())) for _ in range(N)]

dp = [0] * (W + 1)
for w, v in Bs:
    for i in range(W, w - 1, -1):
        dp[i] = max(dp[i], dp[i - w] + v)

print(dp[W])

Solution (Python):
N, W = list(map(int, input().split()))
Bs = []
for i in range(N):
    Bs.append(tuple(map(int, input().split())))

dp = [[0 for _ in range(W + 1)] for _ in range(N + 1)]
for i in range(N - 1, -1, -1):
    for j in range(W + 1):
        dp[i][j] = max(dp[i + 1][j], (dp[i + 1][j - Bs[i][0]] + Bs[i][1]) if j >= Bs[i][0] else 0)

print(dp[0][W])

Solution (Python):
N, W = list(map(int, input().split()))
Bs = []
for i in range(N):
    Bs.append(tuple(map(int, input().split())))

dp = [[0 for _ in range(W + 1)] for _ in range(N)]
for i in range(Bs[N - 1][0], W + 1):
    dp[N - 1][i] = Bs[N - 1][1]
for i in range(N - 2, -1, -1):
    for j in range(W + 1):
        dp[i][j] = max(dp[i + 1][j], (dp[i + 1][j - Bs[i][0]] + Bs[i][1]) if j >= Bs[i][0] else 0)

print(dp[0][W])

Solution (Python):
N,W = [int(s) for s in input().split()]
dp = [[0]*(W+1) for _ in range(N+1)]

for i in range(N):
    w, v = [int(s) for s in input().split()]
    for sum_w in range(W+1):
        if sum_w - w >= 0:
            dp[i+1][sum_w] = max(dp[i][sum_w], dp[i][sum_w-w] + v)
        else:
            dp[i+1][sum_w] = dp[i][sum_w]
print(dp[N][W])

Solution (Python):
N,W = [int(s) for s in input().split()]
dp = [[0]*(W+1) for _ in range(N+1)]

for i in range(1,N+1):
    w, v = [int(s) for s in input().split()]
    for sum_w in range(W+1):
        if sum_w - w >= 0:
            dp[i][sum_w] = max(dp[i-1][sum_w], dp[i-1][sum_w-w] + v)
        else:
            dp[i][sum_w] = dp[i-1][sum_w]
print(dp[N][W])