USACO section 3.1 Humble Numbers(DP)

来源:互联网 发布:brew 安装php开发环境 编辑:程序博客网 时间:2024/05/17 09:46
Humble Numbers

For a given set of K prime numbers S = {p1, p2, ..., pK}, consider the set of all numbers whose prime factors are a subset of S. This set contains, for example, p1, p1p2, p1p1, and p1p2p3 (among others). This is the set of `humble numbers' for the input set S. Note: The number 1 is explicitly declared not to be a humble number.

Your job is to find the Nth humble number for a given set S. Long integers (signed 32-bit) will be adequate for all solutions.

PROGRAM NAME: humble

INPUT FORMAT

 

Line 1:Two space separated integers: K and N, 1 <= K <=100 and 1 <= N <= 100,000.Line 2:K space separated positive integers that comprise the set S.

SAMPLE INPUT (file humble.in)

4 192 3 5 7

OUTPUT FORMAT

The Nth humble number from set S printed alone on a line.

SAMPLE OUTPUT (file humble.out)

27

思路:如果已知前n个丑数要求第n+1个,就只要把集合中的素数依次乘上前n个丑数找到大于第n个丑数的最小的数即是第n+1个丑数;

         不过要是这样直接写绝对爆。优化:用个数组num[];存第i个素数遍历到了第几个丑数,下次只要接着走就行了。

失误点:答案有大于1e9的数,所以const oo=1e9;会错,就是这个提交WA了一次,要用1e10; 

具体看代码:

 

/*ID:nealgav1LANG:C++PROG:humble*/#include<fstream>#include<cstring>using namespace std;ifstream cin("humble.in");ofstream cout("humble.out");const int oo=1e10;const int mm=101000;const int nn=110;int prime[nn],num[mm],pos[nn];int main(){ int m,n;  cin>>m>>n;  memset(num,1,sizeof(num));  memset(pos,0,sizeof(pos));  for(int i=0;i<m;i++)  cin>>prime[i];  int Max,k,last,mid;  num[0]=1;  for(int j=1;j<=n;j++)  { num[j]=oo;//cout<<Max<<"\n";    for(int i=0;i<m;i++)    {  for(int l=0;pos[i]<=j;l++)       {         mid=prime[i]*num[pos[i]];         if(num[j-1]>=mid)pos[i]++;         else break;       }       if(num[j-1]<mid)       { if(num[j]>mid)         {num[j]=mid;k=i;}       }    }pos[k]++;  }  cout<<num[n]<<"\n";}


 

Humble Numbers
Russ Cox

We compute the first n humble numbers in the "hum" array. For simplicity of implementation, we treat 1 as a humble number, and adjust accordingly.

Once we have the first k humble numbers and want to compute the k+1st, we do the following:

for each prime pfind the minimum humble number h  such that h * p is bigger than the last humble number.take the smallest h * p found: that's the next humble number.

To speed up the search, we keep an index "pindex" of what h is for each prime, and start there rather than at the beginning of the list.

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <ctype.h>#define MAXPRIME 100#define MAXN 100000long hum[MAXN+1];int nhum;int prime[MAXPRIME];int pindex[MAXPRIME];int nprime;voidmain(void){    FILE *fin, *fout;    int i, minp;    long min;    int n;    fin = fopen("humble.in", "r");    fout = fopen("humble.out", "w");    assert(fin != NULL && fout != NULL);    fscanf(fin, "%d %d", &nprime, &n);    for(i=0; i<nprime; i++)fscanf(fin, "%d", &prime[i]);    hum[nhum++] = 1;    for(i=0; i<nprime; i++)pindex[i] = 0;    while(nhum < n+1) {min = 0x7FFFFFFF;minp = -1;for(i=0; i<nprime; i++) {    while((double)prime[i] * hum[pindex[i]] <= hum[nhum-1]) pindex[i]++;    /* double to avoid overflow problems */    if((double)prime[i] * hum[pindex[i]] < min) {min = prime[i] * hum[pindex[i]];minp = i;    }}hum[nhum++] = min;pindex[minp]++;    }    fprintf(fout, "%d\n", hum[n]);    exit(0);}
 

 

 

USER: Neal Gavin Gavin [nealgav1]TASK: humbleLANG: C++Compiling...Compile: OKExecuting...   Test 1: TEST OK [0.000 secs, 3752 KB]   Test 2: TEST OK [0.000 secs, 3752 KB]   Test 3: TEST OK [0.000 secs, 3752 KB]   Test 4: TEST OK [0.000 secs, 3752 KB]   Test 5: TEST OK [0.011 secs, 3752 KB]   Test 6: TEST OK [0.032 secs, 3752 KB]   Test 7: TEST OK [0.011 secs, 3752 KB]   Test 8: TEST OK [0.011 secs, 3752 KB]   Test 9: TEST OK [0.000 secs, 3752 KB]   Test 10: TEST OK [0.000 secs, 3752 KB]   Test 11: TEST OK [0.000 secs, 3752 KB]   Test 12: TEST OK [0.086 secs, 3752 KB]All tests OK.

Your program ('humble') produced all correct answers! This is yoursubmission #2 for this problem. Congratulations!

Here are the test data inputs:

------- test 1 ----2 73 5------- test 2 ----4 192 3 5 7------- test 3 ----1 202------- test 4 ----6 100002 3 5 7 11 13------- test 5 ----6 250002 3 5 7 11 13------- test 6 ----8 1000002 3 5 7 11 13 17 19------- test 7 ----7 300002 3 5 7 11 17 23------- test 8 ----7 288882 3 5 11 17 23 31------- test 9 ----1 302------- test 10 ----4 30011 17 23 31------- test 11 ----5 30011 17 19 23 31------- test 12 ----100 1000002 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541