分割数(DFS、DP)

 

https://www.luogu.com.cn/problem/P1025

タイトル説明

整数N k個の各部品、及び空にすることはできません、任意の二つの方式は(順番に関係なく)が異なります。

例えば:。N- = 7 、K = 3は、以下の三つのサブ方法が同じであると考えられます。

1,1,5 ;
1,5,1 ;
5,1,1

Q.どのように多くの異なるポイントシステム。

入力形式

N K(6 < N 2 0 0、2 K 6)

出力フォーマット

1つの整数、すなわち、異なるポイントシステム。

サンプル入力と出力

エントリー 
7  3
輸出
4

説明/ヒント

四法律のポイントの種類:
1,1,5 ;
1,2,4 ;
1,3,3 ;
2,2,3

 

溶液(DFS):

DFSは、考えることは比較的容易であるが、必要剪定。

無効DFS(int型の合計値、int型のステップ、int型のk)

kが合計がはるかに分割したことにより、ステップは、コピーの遠い分割数を表し、上の点の数、k個の点の開始から、この時間を示します。

プログラムの数はそれほど増加数(または減少)の列挙を維持するために、同じではありませんので、我々は、k個のポイントを開始してから繰り返し剪定、(どのように多くの点で)レコードK、この時間を実行することができます。

その上に、<= N-和 - 長い各々は、I *(ステップm)をkにIから列挙として、我々はまた、プルーン実現可能性、。

なぜなら全てが、各サブI、I *が、次いで場合と仮定された後、私はできない電流よりも小さく、次の分の値、(M - 工程)> nの和は、残りの値が十分なポイントだけでなく、電流iはありませんライン、DFSを継続する必要はありません。

 

1の#include <stdio.hの>
 2の#include < ストリング・H>
 3の#include <iostreamの>
 4の#include < ストリング >
 5の#include <math.h>の
 6の#include <アルゴリズム>
 7の#include <ベクトル>
 8#含む<スタック>
 9の#include <キュー>
 10の#include < セット >
 11の#include <地図>
 12の#include <sstream提供さ>
 13  のconst  int型 INF = 0x3f3f3f3f 14 typedefの長い 長いLL。
 CONST  INT MOD = 1E9 + 7 ;
 16  CONST  INT MAXN = 1E4 + 10 ;
 17  使用して 名前空間STD;
 18である 
。19  int型N-、M;
 20である INT ANS;
 21は 
22である ボイド(DFS をint SUM、INT STEP、INT K)// Kが表します番号を付し、繰り返しの剪定
23は {
 24      IF(STEP == M)
 25      {
 26で         IF(SUM N - ==)ANS ++ ;
 27          リターン;
 28     }
 29      のためintは iはkは= I ++; iが(M-工程*)<= N-和)// 可行性剪枝
30          DFS(I +和、ステップ+ 1 、I)。
31  }
 32  
33  のint main()の
 34  {
 35      の#ifdefデバッグ
 36      freopenは(" SAMPLE.TXT "" R " 、STDIN)。
37      #endifの
38      
39      のscanf(" %D%D "、&​​N、&M)。
40の      DFS(001);
41      のprintf(" %dの\ n " 、ANS)。
42      
43      リターン 0 44 }

 

 

 

対処方法2(DP):

DP [i] [j]はiがプログラム部品jの数に分割される整数です。

J番号 - 各請求項のタイトルが空でないようにまず、I整数得れば、それは第1の部分が配置されている位置番号j jに残り私を考え出す必要があります。

そして、それをどのように扱うかの残りの数?(DP [IJ] [1])、それらのすべてに割り当てることができ、重複(DP [IJ] [2])に割り当てられ、...、jは[DP(部品に割り当てることができ、 IJ] [J])、点のそれぞれまとめ、及びDPである[I] [J]。

しかし、[I-1]〜[J-1]この式は、単純なようではありません、単純な式を得るために、私たちはその後、DPを求めます

 

上記二つの式を比較すると、得られます

 

 

式に対応する二つの例:

1. 1、残りのI-1、J-1、DPに対応する部分に分割する[I-1] [Jの一部のみがあり -1]は。
2.各値が1を置くために、各コピーの最初のJの部分に、すなわち、1よりも大きい場合、次いでijはDPに対応し、その後、それはその後のJ部に分散IJを残し[IJ ] [J]。(この時点で、私はI〜Jよりも大きくなければなりません)

 

1の#include <stdio.hの>
 2の#include < ストリング・H>
 3の#include <iostreamの>
 4の#include < ストリング >
 5の#include <math.h>の
 6の#include <アルゴリズム>
 7の#include <ベクトル>
 8#含む<スタック>
 9の#include <キュー>
 10の#include < セット >
 11の#include <地図>
 12の#include <sstream提供さ>
 13  のconst  int型 INF = 0x3f3f3f3f 14 typedefの長い 長いLL。
 const  int型 MOD = 1E9 + 7 16  CONST  INT MAXN = 1E4 + 10 17  使って 名前空間はstdを、
18  
19  のint DP [ 205 ] [ 10 ]。
20  
21  のint main()の
 22  {
 23      の#ifdefデバッグ
 24      freopenは(" SAMPLE.TXT "" R " 、STDIN)。
25      #endifの
26      
27      整数N、M。
28      のscanf("%D%D "、&​​N、&M);
 29      INTは私= 1 ; I <= N; I ++ 30      {
 31          DP [I] [ 1 ] = 1 ;
 32          INT J = 2、J < = M; J ++ 33          {
 34              であれば(I == j)はDP [I] [J] = 1 ;
 35              そう なら(I> J)DP [I] [J] = DP [I- 1 ] [J- 1 ] + DP [I- J] [J];
 36          }
 37      }
 38     printf(" %D \ n " 、DP [n]は[M])。
39      
40      リターン 0 ;
41 }

 

 

 

 

-

おすすめ

転載: www.cnblogs.com/jiamian/p/12275461.html