一个典型的动态规规划用

 DP 有两种类型,一种是:Top-Down 一种是:Bottom-Up 。 DP 的典型的应用有几种:
 1、Coin change : is the problem of finding the number of ways of making changes for a particular amount of cents,n, using a given set of denominations d[1...m].
   The problem is defined follows:
    Give an integer n, and a set of integers s={s[1],s[2]...s[m]} , How many ways can one express n as a linear combination of s[1..m] with non-negative coefficent.
   Recursive formulation :  f(n,m) = f(n,m-1) + f(n - i * s[m], m  );
                       f(0,m) = 1 ; f(n<0,m) = 0 ; f(n>=1,m<=0)= 0;

   问题:Square   Coins 
                      Time   limit:   1   Seconds       Memory   limit:   32768K       
  People   in   Silverland   use   square   coins.   Not   only   they   have   square   shapes   but   also   their   values   are   square   numbers.   Coins   with   values   of   all   square   numbers   up   to   289   (=17^2),   i.e.,   1-credit   coins,   4-credit   coins,   9-credit   coins,   ...,   and   289-credit   coins,   are   available   in   Silverland.   
  There   are   four   combinations   of   coins   to   pay   ten   credits:   
  
  ten   1-credit   coins, 
  one   4-credit   coin   and   six   1-credit   coins, 
  two   4-credit   coins   and   two   1-credit   coins,   and 
  one   9-credit   coin   and   one   1-credit   coin.   
  
  Your   mission   is   to   count   the   number   of   ways   to   pay   a   given   amount   using   coins   of   Silverland.   
  
  
  Input 
  
  The   input   consists   of   lines   each   containing   an   integer   meaning   an   amount   to   be   paid,   followed   by   a   line   containing   a   zero.   You   may   assume   that   all   the   amounts   are   positive   and   less   than   300.   
  
  
  Output 
  
  For   each   of   the   given   amount,   one   line   containing   a   single   integer   representing   the   number   of   combinations   of   coins   should   be   output.   No   other   characters   should   appear   in   the   output.   
  
  
  Sample   Input 
  
  2 
  10 
  30 
  0  
 递归解法:
 
#include < iostream.h >     
  
int    A[ 18 ]    =    { 0 , 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 , 100 , 121 , 144 , 169 , 196 , 225 , 256 , 289 };    
  
int    f( int , int );    
  main()    
  {    
        
int    n;    
        cin
>> n;    
        
while (n)    
        {    
              cout
<< f(n, 17 ) << endl;    
              cin
>> n;    
        }    
        
return     0 ;    
  }    
  
int    f( int    n, int    m) // 用最大面值为m*m的硬币组成n的方法数    
  {    
        
if (m == 1 )    
              
return     1 ;    
        
if (n == 0 )    
              
return     1 ;    
        
int    sum    =     0 ;    
        sum   
+=    f(n,m - 1 );    
        
while (n    >=    A[m])    
        {    
              n   
-=    A[m];    
              sum   
+=    f(n,m - 1 );    
        }          
        
return    sum;    
  }     

DP 解法:
#include < iostream >     
  
using     namespace    std;    
  
int    c[ 301 ][ 18 ];    
  
void    init()    
  {    
  
for ( int    i = 0 ;i <= 300 ;i ++ )    
  
for ( int    j = 0 ;j <= 17 ;j ++ )    
  c[i][j]
= 0 ;    
  c[
0 ][ 0 ] = 1 ;    
  
for ( int    r = 1 ;r <= 300 ;r ++ )    
  
for ( int    l = 1 ;l <= 17 ;l ++ ){    
  
int    t = r,tt = l * l;    
  
while ((t -= tt) >= 0 )    
  
for ( int    k = 0 ;k < l;k ++ )    
  c[r][l]
+= c[t][k];    
  }    
  }    
  
int    count( int    n)    
  {    
  
int    sum = 0 ;    
  
for ( int    k = 0 ;k <= 17 ;k ++ )   sum += c[n][k];    
  
return    sum;    
  }    
  
int    main()    
  {    
  
int    n;    
  init();    
  cin
>> n;    
  
while (n){    
  cout
<< count(n) << endl;    
  cin
>> n;    
  }    
  
return     0 ;    
  }   

你可能感兴趣的:(Integer,express,input,iostream,Shapes,combinations)