主要的思想就是dp, 转移方程不大明显,但是比较容易想。 下一个丑数由之前的丑数乘{2,3,5,7}中最小且大于上一个数的数得到。先把所有数算出来然后打表输出。输出太恶心了,还考人英语。。
/*
PROG: humble number
LANG: C++11
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <time.h>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define eps 10e-8
typedef long long ll;
const int N = 100010;
const ll MOD = 1000000007;
const int INF = 0x7fffffff;
ll humble[6000];
int prime [4]= {2,3,5,7};
int main()
{
int n, i, j, k;
ll cur, minn;
int maxn = 5842;
humble[1] = 1;
humble[2] = 2;
for(i = 3; i <= maxn; i++){
minn = INF;
k = 1;
for(j = 0; j < 4; j++){
for(; k < i; k++){<span style="white-space:pre"> </span>// instead of making k = 1 every time
cur = prime[j] * humble[i-k]; // because prime is in increasing order
if(cur <= humble[i-1])
break;
minn = min(minn, cur);
}
}
humble[i] = minn;
}
while(scanf("%d", &n)){
if(!n)
break;
cout << "The " << n;
if(n%10 ==1 && n%100 != 11)
cout << "st humble number is ";
else if(n%10 == 2 && n%100 != 12)
cout << "nd humble number is ";
else if(n%10 ==3 && n%100 != 13)
cout << "rd humble number is ";
else
cout << "th humble number is ";
cout << humble[n] << "." << endl;
}
return 0;
}
中间剪枝了一下,比网上流行的算法稍微快一点