(統合)P2089チキン

ソリューション:

 

する#include <stdio.hの>
INT N、RET = 0、[10000] [10]。
int型のP(INT C、INT S){
 I int型。
 以下のための(iは= 1; I <= 3; I ++){
   S + = I。
   IF(C == 9){
     (N == S)であれば{
       [RET] [C] = I。
       RET ++;
       1を返します。
     }他{
      S- = I。
       継続する;
     }
   }そうでなければ{
     (P(C + 1、S)){もし
      [RET-1] [C] = I。
      1を返します。
    }
  }
 
 }
}
int型のmain()
{
 int型I、J。
 scanf関数( "%のD"、&N);
 IF(N> 30 && N <10){
  のprintf( "0")。
 }他{
  int型B = P(0,0)。
 

 printf( "%dの\ n"は、RET)。
 {(I ++; I <RET I = 0)するための
  ための(J = 0であり、j <10; J ++){
   のprintf( "%dの"、[I] [J])。
  }
  のprintf( "\ n");
 }
 0を返します。
}
 
残念ながら、これは、戻り値が除去された後、再帰的解決策の一つだけ出ているデータ記憶機能に入り、アレイ内の次の行を満たすために、一度データをコピーし、サイクルが継続します。だから、少し退屈を取得します。
単純なポイントは、次に、実際には、一次元アレイは場合アコード二次元配列にコピーの数を設定れる、組み合わせをテストするために使用することができます。
M1 [ 10000] [ 10]、M2 [ 10]。
 
ボイドP INT合計、INT A){
    IF(A == 10){
        IF(全N - ==){
            ため(INT J = 0; J < 10; J ++)M1 [種類] [J] = M2 [J ]; //は~~要件を満たすまで保存
            ++種類;
        }
    }
    他には、IF(合計> = N-); で//少し最適化の
   
      のために(int型I = 1; I <= 3; I ++){
          M2 [A] = I;
          peiliao(合計+ I、A + 1); //この事実も違いはありませんのために10。
      }
}
 
正解は正直、我々はまた、列挙したかったことを、言った、列挙、列挙は二回、完全に歪曲し、インターネットを検索され、1は少しシンプルを感じ、そして第二に、それかもしれないアルゴリズムの複雑さが高すぎると、結果ではありません高いです。

おすすめ

転載: www.cnblogs.com/lijiahui-123/p/12243524.html