ACM题解报告——HD1058

   今天解了HDOJ上的1058题:http://acm.hdu.edu.cn/showproblem.php?pid=1058

   这是一道关于动态规划(dynamic programming)的题目,适用DP的算法解决的问题一般都有3个特性:最优化原理、无后向性、子问题重叠性质。

   最优化:如果问题的最优解所包含的子问题的解也是最优,那么父问题的解也是最优的,该问题具有最优子结构。

   无后向性:若某个阶段的状态确定之后,那么就不会受这个状态后面的决策所影响,也就是说某状态以后的过程不会影响以前的状态,而只与当前的状态有关。

   有重叠子问题:指子问题间不是相互独立的,一个子问题的解可能在下一个问题中被多次使用,这是动态规划区别于其它算法的一大特征,也是其一大优势,让问题变得不再那么冗杂。在本题中,每次的map[i]都是用前面得出的map[]值乘以4个因子中的某个得到的。

   具体看看这道题,这道题的大体意思就是要你找出以2,3,5,7为因子的数(我们姑且称它们为因子数),按升序排列,然后输入一个n(1<=n<=5842),表示要求输出第n个因子数。具体的输出格式看输出样例,这里输出格式违背了英语的构词原则(估计是出这道题的人不太细心- -),第111个为111th,而121为121st......

代码如下:

 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 
 5 int map[6000];//开辟一个足够大的数组
 6 int min( int a,int b,int c,int d)
 7 {//取a,b,c,d中的最小值
 8   return (a<b?a:b)<(c<d?c:d)?( a<b?a:b):(c<d?c:d);
 9 }
10 void humble( )
11 {
12   int i,j,k,p,x;
13   i=j=k=p=1;
14   for(x=2;x<=5842;x++)
15     {//算法核心:每次选出最小的值作为因子数,然后其对应的min中的map值被替换成下一个因子数(按升序)
16   map[x]=min( map[i]*2,map[j]*3,map[k]*5,map[p]*7);
17   if(map[x]==map[i]*2)  i++;
18   if(map[x]==map[j ]*3)  j++;
19   if( map[ x]==map[k]*5)  k++;
20   if(map[x]==map[p]*7)  p++;
21  }
22 }
23 int main( )
24 {
25   int n;
26   map[ 1]=1;
27   humble( );//打表
28   while( scanf("%d",&n)&&n)
29     {//特别注意输出格式控制
30   if(n%10==1&&n%100!=11)  cout<<"The "<<n<<"st humble number is "<<map[n]<<"."<<endl;
31 if(n%10==2&&n%100!=12 )   cout<<"The "<<n<<"nd humble number is "<<map[n]<<"."<<endl;
32 if(n%10==3&&n%100!=13)     cout<<"The "<<n<<"rd humble number is "<<map[n]<<"."<<endl;
33 if( n%10>=4||n%10==0)    cout<<"The "<<n<<"th humble number is "<<map[n]<<"."<<endl;
34 if( n%100==11||n%100==12||n%100==13)  cout<<"The "<<n<<"th humble number is "<<map[n]<<"."<<endl;
35  }
36   return 0;
37 }

 

posted @ 2013-05-16 21:33  paradise in hell  Views(179)  Comments(0Edit  收藏  举报