应用了递推的思想,一个数的形式必然是2^p1 * 3^p2 * 5 ^p3 * 7 *p4 的形式,所以当前一定是由前面某一个数乘上2,5,7,3中的某一个获得的,而且是乘积最小的,所以我们标记当前最靠前的没有乘某一个因子的数,也就是当前某个因子对应的可以乘取的最小的数,可以采取如下方式进行动态规划,代码很好理解
当然更简单的还有枚举的做法
在我的解题报告中也有另一篇枚举法的解体方法
代码如下:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #define MAX 6000 using namespace std; typedef long long LL; LL num[MAX]; void init ( ) { num[1] = 1; int l1,l2,l3,l4; l1 = l2 = l3 = l4 = 1; for ( int i = 2 ; i <= 5842 ; i++ ) { num[i] = min ( min ( num[l1]*2, num[l2]*3) , min ( num[l3]*5 , num[l4]*7)); if ( num[i] == num[l1]*2 ) l1++; if ( num[i] == num[l2]*3 ) l2++; if ( num[i] == num[l3]*5 ) l3++; if ( num[i] == num[l4]*7 ) l4++; } } int main ( ) { int n; init ( ); while ( ~scanf ( "%d" , &n ), n ) { char s[50]; if ( (n/10)%10 != 1 ) { if ( n%10 == 1 ) sscanf ( "st" , "%s" , s ); else if ( n%10 == 2 ) sscanf ( "nd" , "%s" , s ); else if ( n%10 == 3 ) sscanf ( "rd" , "%s" , s ); else sscanf ( "th" , "%s" , s ); } else sscanf ( "th" , "%s" , s ); printf ( "The %d%s humble number is %lld.\n" , n , s ,num[n] ); } }