トピックリンクします。http://poj.org/problem ID = 1742?
条件を計算する数が最も計算値ではなく、満たされている一般的なナップザック問題とは異なり、アイデアは、書籍のアナロジーの先頭に従うことです。
DP [I] [J]:=コインの種類と私はjの前まで追加することができます
再発:DP [I] [J] =(DP [I - 1] [J - K * A [I])が真であります
しかし、MLEは、本当に驚いていないこと、そしてうん、我々は唯一の2次元配列をあきらめることができ、大きな配列が問題になります開きました。
DP [J]:= i番目のサイクルで前jは残数にコインのi番目のコイン型アップ(と-1不図示示す)とフロントI-1を示し、アップする時間に、それは、そのi番目のサイクルを意味します状態
ACコード:
1の#include <cstdioを> 2の#include <CStringの> 3の#include <アルゴリズム> 4の#include <iostreamの> 5 の#define MAX_N 101 6 使用して 名前空間STDを、 7 整数N、M。 8 INT [MAX_N]、C [MAX_N]。 9 int型 DP [ 100005 ]。 10 11 ボイド解く(){ 12 のmemset(DP、 - 1、はsizeof (DP))。 13 DP [ 0 ] = 0 ; 14 のための(int型iは= 0 ; N I <; I ++ ){ 15 のために(INT J = 0 ; J <= Mであり、j ++ ){ 16 であれば(DP [j]> = 0 ) 17 、DP [J] = C [i]は、 18 他の 場合(J <[I] || DP [JA [I] <= 0 ) 19 、DP [J] = - 1 。 20 他 21 DP [J] = DP [JA [I]] - 1 。 22 } 23 } 24 INT ANS = 0 。 25 のために(INT iは= 1 ; iが<= M; I ++ ) 26 であれば(DP [I]> = 0)ANS ++ 。 27 のprintf(" %dの\ n " 、ANS)。 28 } 29 30 INTメイン(ボイド){ 31 ながら(scanf関数(" %D%D "、&N、&M)&&(N || M)){ 32 のために(INT iは= 0を、I <N; I ++)のscanf (" %dの"、および[I])。 33 のための(int型 J = 0; J <N; J ++)のscanf(" %dの"、&C [J])。 34 )(解きます。 35 } 36 37 戻り 0 ; 38 }