リンク:https://www.acwing.com/problem/content/5/
ありN財の種類と容量Vの バックパックは。
最初の までの記事iはS I 断片を、各ボリュームは、V 、I、の値であるW I。
これはバックパックにアイテムを解決する、バックパックの物品容量、最大値の和の総容積を超えることができません。
最大出力値。
入力形式
二つの整数の最初の行、N 、Vは、それぞれが商品の種類やバックパックの体積を表し、スペースで区切られました。
そこであるN個の 行は、三つの整数の各行V I 、W I 、S Iは、それぞれ表す、スペースで区切らIアイテム、数量および値の体積。
出力フォーマット
最大値を表す出力アン整数。
データ範囲
0 < N ≤ 千
0 < V ≤ 2000
0 < V iは、wはI 、sはI ≤ 2000
ヒント:
このタイトルは、複数のバイナリ最適化のバックパックを調べます。
サンプル入力
4 5
1 2 3
2 4 1
3 4 3
4 5 2
出力例:
10
解题思路:把多重背包变成01背包
二进制优化:如果说把其物品都分成一分的话,会超时,
所以其子问题就是:一个数n,最少要多少个数才能把从1-n中的所有数表示出来;
答案是:log2(n)上取整个数
如:7的 1 2 4(2^0 2^1 2^2)
上面7是个特殊的例子:
再如10:如果用 1 2 4 8 表示的话会超过10
所以用1 2 4 3(10-1-2-4)
AC代码:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 N = 20110 ; INT V [N]、[N] wは、[N]です。 INTのDP [N]。 INT のmain() { int型 N、M、V1、W1、S、カット= 0 。 CIN >> N >> M。 以下のために(INT iが= 1 ; I <= N; I ++ ){ CIN >> V1 >> W1 >> S。 INTはk = 1 。 一方、(K <= S){ カット++ ; V [カット] = V1 * K。 [カット]、W = W1 * K。 S - = K。 K * = 2 ; } もし、(S> 0 ){ カット ++ 。 V [カット] = V1 * S。 [カット]、W = W1 * S。 } } N = カット。 以下のために(INT iが= 1 ; I <= N; I ++ ){ ため(INT J = M; J> = V [i]は、j--){ DP [J] = MAX(DP [J]、DP [JV [I] + W [I])。 } } のprintf(" %dの" 、DP [M])。 }