应用了递推的思想,一个数的形式必然是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] );
}
}