質問の意味:コインの1-Nの種類の中から、各コインの額面は1-Nで、無制限の数、Kのどのように多くのポートフォリオ全体、あなたにK、コインを使用してTの断片の総数の額面を与える、頼みます
入力は、ほんの数Kである場合、それはコインK 0、Kの組み合わせの使用を示し
2つのK数N1を、0-N1指示コイン、Kの組み合わせであります
3つの数字はK、N1、N2、N1-N2指示コイン、Kの組み合わせが存在する場合
サンプル入力
6
6 3
6 2 5
6 1〜6の
サンプル出力
11
7
9
11
問題解決のアイデア:
DP、DP [j] [k]はDP [J] [K] + DP [JI] [K-1] =
DP [j] [k]は番号k jを用いて、プログラムの意味は、コインの組み合わせです。
式の意味は、前の合計のコイン+ Iの額面の使用です。
生成DP配列の順序は、列挙を生成するために繰り返さないことに留意されたいです。
まず、1を使用します。2は、次に起動し、[3を添加開始し、Nに追加されています
これは、プログラムの同じ数をカウント倍増しません。
書式#include < 文字列 > の#include <iostreamの> の#include <sstream提供> する#include <マップ> 書式#include <memory.h> 書式#include <ベクトル> の#include <アルゴリズム> 書式#include <キュー> の#include <ベクトル> 書式#include <スタック> の#include <math.h>の 書式#include <iomanip> の#include <ビットセット> の#include " のmath.h " 名前空間CC { 使用STD :: COUTと、 使用してのstd ::てendlを。 使用してのstd :: cinをします。 使用してstd ::マップ。 使用してのstd ::ベクトルを、 使用してのstd :: 文字列を。 使用してのstd ::並べ替えを。 使用してのstd :: PRIORITY_QUEUEを。 使用してのstd ::大きいを。 使用してのstd ::ベクトルを、 使用してのstd ::スワップを。 使用してのstd ::を積み重ねます。 使用してのstd ::ビットセットを。 使用してのstd ::にstringstreamを。 constexprののINT N = 306 。 // のconst int型N = 7; 長い 長いDP [N] [N]。 ボイドのinit() { memsetの(DP、0、はsizeof (DP))。 DP [ 0 ] [ 0 ] = 1 。 以下のために(int型 i = 1 ; iがNを<I ++は) { ための(int型 J = I; J <N; J ++ ) { ための(int型のk = 1 ; K <N; kは++ ) { DP [J] [K] + = DP [JI] [K- 1 ]。 } } } } ボイドは、(解決) { 文字列STR。 その中に(); 一方(のgetline(CIN、STR)) { 場合(str.length()== 0 ) 続けます。 stringstream罪(STR); int型 N1 = - 1、N2 = - 1、N3 = - 1 ; 罪 >> N1。 罪 >> N2; 罪 >> N3。 長い 長い合計= 0 ; もし(N1 = - !1 && N2 = - !1 && N3 = - !1 ) { N2 = STD ::分(N2、300 )。 N3 = STD ::分(N3、300 )。 用(int型 ;私は= N3 <I ++はiは= N 2 ) 合計 + = [N1] [i]のDPと、 } そう であれば(N1 = - !1つの && N2 =! - 1 ) { N2 = STD ::分(N2、300 )。 以下のために(int型 i = 0 ; iは= N2 <; iは++ ) 合計 + = DP [N1] [I]。 } 他 { ため(int型 i = 0 ; iは= N1 <; iは++ ) 合計 + = DP [N1] [I]。 } COUT <<総<< ENDL。 } } }。 INT メイン() { #ifndefのONLINE_JUDGE freopenは(" D://1.text "、" R " 、STDIN)。 #endifの // !ONLINE_JUDGEの CC ::()を解きます。 リターン 0 ; }