1. 程式人生 > >HDOJ-1058 Humble Numbers(動態規劃)

HDOJ-1058 Humble Numbers(動態規劃)

連結:HDOJ-1058

Problem Description

A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, … shows the first 20 humble numbers.

Write a program to find and print the nth element in this sequence

Input

The input consists of one or more test cases. Each test case consists of one integer n with 1 <= n <= 5842. Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line saying “The nth humble number is number.”. Depending on the value of n, the correct suffix “st”, “nd”, “rd”, or “th” for the ordinal number nth has to be used like it is shown in the sample output.

Sample Input

1
2
3
4
11
12
13
21
22
23
100
1000
5842
0

Sample Output

The 1st humble number is 1.
The 2nd humble number is 2.
The 3rd humble number is 3.
The 4th humble number is 4.
The 11th humble number is 12.
The 12th humble number is 14.
The 13th humble number is 15.
The 21st humble number is 28.
The 22nd humble number is 30.
The 23rd humble number is 32.
The 100th humble number is 450.
The 1000th humble number is 385875.
The 5842nd humble number is 2000000000.


題目大意:

因子只有2,3,5,7的數稱為醜數(1也是醜數),找到第N個醜數(N<=5842)


分析:

思路不難想,對已有的所有數*2,*3,*5,*7,從中選出能放在下一位的數。
但是知道了這個卻一直想不出好的dp方法。。。 後來看到別人的狀態轉移方程豁然開朗。。。
如下:

dp[i] = min( dp[two] * 2 , dp[three] * 3 , dp[five] * 5 , dp[seven] * 7 )

two,three,five,seven是*2,*3,*5,*7 進行到第幾個數的位置標記,這樣保證了已有的所有數都進行 *2,*3,*5,*7而且只進行一次,同時進行min比對。
得出的 dp[i] 會等於其中某一個結果(或多個結果:*2,*3,*5,*7可能有相同值),就讓對應位置標記+1,這樣同時能保證進行min對比的都是相對小的值。

此外,就是這題輸出的坑,結尾為1,2,3並且結尾不是11,12,13的N後面要加上"st",“nd”,“rd”,其他的加"th"。


以下程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	int dp[6000];
	int i,two=1,three=1,five=1,seven=1;
	dp[1]=1;
	for(i=2;i<=5842;i++)
	{
		dp[i]=min(min(dp[two]*2,dp[three]*3),min(dp[five]*5,dp[seven]*7));
		if(dp[i]==dp[two]*2)
			two++;
		if(dp[i]==dp[three]*3)
			three++;
		if(dp[i]==dp[five]*5)
			five++;
		if(dp[i]==dp[seven]*7)
			seven++;
	}
	int N;
	while(scanf("%d",&N)&&N!=0)
	{
		printf("The %d",N);
		if(N%10==1&&N%100!=11)
			printf("st");
		else if(N%10==2&&N%100!=12)
			printf("nd");
		else if(N%10==3&&N%100!=13)
			printf("rd");
		else
			printf("th");
		printf(" humble number is %d.\n",dp[N]);
	}
	return 0;
}