POJ1338Ugly Numbers(DP)

http://poj.org/problem?id=1338

第一反应就是DP,DP[i] = min{2*DP[j], 3*DP[k], 5*DP[p] j,k,p<i};于是枚举一下0~i-1即可

后来听到室友说,可以通过上一个×2、×3、×5得到。于是搞了个优先队列预处理。

后来看了一下以前A的代码。O(n)的。。。(虽然不是我自己做出的= =)

时间都是0Ms

O(n^2)和O(nlogn)的:

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define MAX(a,b) (a > b ? a : b)
17 #define MIN(a,b) (a < b ? a : b)
18 #define mem0(a) memset(a,0,sizeof(a))
19 
20 typedef long long LL;
21 const double eps = 1e-12;
22 const int MAXN = 1005;
23 const int MAXM = 5005;
24 
25 struct NODE
26 {
27     int num;
28     int flag;
29     NODE(){}
30     NODE(int _num, int _flag){num=_num;flag=_flag;}
31     bool operator < (NODE B)const
32     {
33         return num > B.num;
34     }
35 };
36 int DP[1610], N;
37 
38 //void init()
39 //{
40 //    int time = 0;
41 //    for(int i=1;i<=1500;i++) DP[i] = INF;
42 //    DP[1] = 1;  int now = 1;
43 //    int two=1, three=1, five=1;
44 //    for(int i=2;i<=1500;i++)
45 //    {
46 //        for(int j=min(two,min(three,five));j<i;j++)
47 //        {
48 //            time ++;
49 //            if(DP[j]*2 > now && DP[i]>DP[j]*2){ DP[i] = min(DP[i], DP[j]*2); two = j;break;}
50 //            if(DP[j]*3 > now && DP[i]>DP[j]*3){ DP[i] = min(DP[i], DP[j]*3); three = j;}
51 //            if(DP[j]*5 > now && DP[i]>DP[j]*5){ DP[i] = min(DP[i], DP[j]*5); five = j;}
52 //        }
53 //        now = DP[i];
54 //    }
55 //    //printf("Time=%d\n", time);
56 //}
57 
58 void init()
59 {
60     priority_queue<NODE>q;
61     NODE U;  U.num=1; U.flag=-1;
62     q.push(U);
63     int num = 1, tot = 1;
64     while(1)
65     {
66         U = q.top(); q.pop();
67         DP[num++] = U.num;
68         if(num>1500) return ;
69         if(tot > 1600) continue;
70         q.push(NODE(U.num*5, 1));                  tot++;
71         if(U.flag<=0) {q.push(NODE(U.num*3, 0));   tot++; }
72         if(U.flag<=-1){q.push(NODE(U.num*2, -1));  tot++; }
73     }
74 }
75 
76 int main()
77 {
78    // printf("%d\n", (int)(1600 * (log(1600.0)/log(2.0))));
79    // freopen("test.in", "r", stdin);
80     init();
81     while(~scanf("%d", &N) &&N)
82     {
83         printf("%d\n", DP[N]);
84     }
85     return 0;
86 }

O(n)的:不是我写的= =

 1 #include <stdio.h>
 2 int min(int a,int b,int c)
 3 {
 4     if(b<a)
 5     a=b;
 6     if(c<a)
 7     a=c;
 8     return a;
 9 }
10 int main()
11 {
12     int n;
13     int i2_mul;
14     int i3_mul;
15     int i5_mul;
16     unsigned long ugly[1501];
17 
18     i2_mul = 1;
19     i3_mul = 1;
20     i5_mul = 1;
21     ugly[1]=1;
22 
23     for(  int i = 2; i <= 1500; i++ )
24     {
25         ugly[i] = min(ugly[i2_mul]*2,ugly[i3_mul]*3,ugly[i5_mul]*5);
26         if(ugly[i] == ugly[i2_mul]*2 )
27             i2_mul++;
28         if(ugly[i] == ugly[i3_mul]*3 )
29             i3_mul++;
30         if(ugly[i] == ugly[i5_mul]*5)
31             i5_mul++;
32     
33     }
34 
35 
36     while(true)
37     {
38         scanf("%d",&n);
39 
40         if( n == 0 )
41             break;
42 
43         printf("%d\n",ugly[n]);
44 
45     }
46 
47     return 0;
48 }

 

posted @ 2013-11-26 09:17  再见~雨泉  阅读(291)  评论(0编辑  收藏  举报