1. 程式人生 > >USACO Humble Numbers

USACO Humble Numbers

滿足 lld n) include sca col ont numbers div

USACO

Humble Numbers

    這題主要是兩種做法,第一種是比較常(jian)規(dan)的-------------用pq(priority_queue)維護,每次取堆中最小值(小根堆),用這個值松(mei)弛(ju)

  一遍所有的素數,大概是O(n*k*logn)的,所以--------閉眼睛T啊!!

    冷靜一下,我們來看第二種做法:

  顯然,在第一種做法中,我們重復計算了堆中的好多值,而這些我們可以通過記錄一個地址來優化。

  我們假設已經求出了前i個醜數,對於第(i+1)個醜數,我們可以枚舉所有的素數並且記錄這個素數已經枚舉到了哪個醜數,這樣我們在接下來的求解過

  就不會重復那些當前地址之前的所有醜數。

    附上想醜數一樣醜陋的代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a[110];
int dis[110];
ll ugly[100100];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    a[0]=1;
    for(int
i=1;i<=n;i++) { scanf("%lld",&a[i]); } sort(a+1,a+n+1); ugly[0]=1; memset(dis,0,sizeof(dis)); int minn; for(int i=1;i<=m;i++) { minn=n;//記錄哪一個值恰好滿足條件 for(int j=1;j<=n;j++) { if(a[j]*ugly[dis[j]]>ugly[i-1]&&a[j]*ugly[dis[j]]<a[minn]*ugly[dis[minn]]) minn
=j; } ugly[i]=a[minn]*ugly[dis[minn]];//更新滿足條件者 dis[minn]++;//更新滿足條件者 for(int j=1;j<=n;j++) { while(a[j]*ugly[dis[j]]<ugly[i]) dis[j]++; if(a[j]*ugly[dis[j]]==ugly[i]) dis[j]++; } } printf("%lld",ugly[m]); return 0; }

  小結:本題所得到的想法及錯誤。

      1.沒更新主值(ugly);

      2.35行是重要的,因為如果這個素數的地址並沒有滿足要求,那麽它在下一次美劇

  

USACO Humble Numbers