hdu 1058 Humble Numbers

算法分析:典型的DP!

1 ->?

1 ->2=min(1*2,1*3,1*5,1*7)
1 ->2 ->3=min(2*2,1*3,1*5,1*7)
1 ->2 ->3 -> 4 = min(2*2,2*3,1*5,1*7)
1 ->2 ->3 -> 4 ->5= min(3*2,2*3,1*5,1*7)
状态转移方程

F(n)=min(F(i)*2,F(j)*3,F(k)*5,F(m)*7)(n>i,j,k,m)    特别的: i,j,k,m 只有在本项被选中后才移动。对应的i,j,k,m要++ 。

PS:一次移动可能不止一项,若四项中有几项相同时,它们也得移动。这点一直没考虑清楚,浪费了很长时间。

AC代码:

#include<stdio.h>

inline int min(int a, int b)
{
	return (a)<(b)?(a):(b);
}


int f[5845];
int main(){
	int n,i,j,d,k,m;
	f[0]=1;
	f[1]=1;
	n=25;
	d=j=1;
	k=m=1;
	for(i=2;i<=5842;i++){
		int temp=min(min(f[d]*2,f[j]*3),min(f[k]*5,f[m]*7));
	
		f[i] = temp;
	
		if(temp == f[d]*2){
			d++;
		}
		if(temp==f[j]*3){

			j++;
		}
		if(temp==f[k]*5) {
		
			k++;
		}
		if(temp==f[m]*7) {
			m++;
		}

	}
	while(scanf("%d",&n)!=EOF&&n!=0){
		if(n%10==1 && n%100 != 11){//个位数是1,但十位数不是1
			printf("The %dst humble number is %d.\n",n,f[n]);
		} else if(n%10==2 && n%100 != 12){//个位数是2,但十位数不是1
			printf("The %dnd humble number is %d.\n",n,f[n]);
		} else if(n%10==3 && n%100 != 13){//个位数是3,但十位数不是1
			printf("The %drd humble number is %d.\n",n,f[n]);
		} else
			printf("The %dth humble number is %d.\n",n,f[n]);

	}

	return 0;
}





你可能感兴趣的:(hdu 1058 Humble Numbers)