hdu - 4228 - Flooring Tiles - dfs

對於任何正整數x,起約數的個數記做g(x).例如g(1)=1,g(6)=4.
如果某個正整數x滿足:對於任意i(0<i<x),都有g(i)<g(x),則稱x爲反素數.
現在給一個N,求出不超過N的最大的反素數.
比如:輸入1000 輸出 840
思維過程:
求[1..N]中約數在大的反素數-->求約數最多的數
如果求約數的個數 756=2^2*3^3*7^1
(2+1)*(3+1)*(1+1)=24
基於上述結論,給出算法:按照質因數大小遞增順序搜索每一個質因子,枚舉每一個質因子
爲了剪枝:
性質一:一個反素數的質因子必然是從2開始連續的質數.
因爲最多只需要10個素數構造:2,3,5,7,11,13,17,19,23,29

性質二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....


題意:http://acm.hdu.edu.cn/showproblem.php?pid=4228

      給你m個小方塊,我們知道m塊小方塊能組成n個長方形。

     現給定n,求最小的m。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf (1LL << 60)
typedef __int64 lld;
lld p[1000];
int n;
lld prime[25]= {2,3,5,7,11,13,17,19,23,29,31,37,41,53,59,61};

void Make(int facnum, int limit, lld x, int k){// 1 60 1 0
    if(facnum > 150 || x > inf) return ;
    if((p[facnum] != -1 && p[facnum] > x) || p[facnum] == -1) p[facnum] = x;
    if(k > 16) return ;

    lld tmp = x;
    for(int i = 1; i <= limit; i ++){
        tmp *= prime[k];
        if(tmp > inf) break;
        Make(facnum * (i + 1), i, tmp, k + 1);
    }
}

int main()
{
    memset(p,-1,sizeof(p));
    p[1]=1;
    Make(1,60,1,0);
    while(scanf("%d",&n)!=EOF && n){//p[i] 爲有約數個數爲i的最小數
        lld ans=((lld)1<<60);
        if(p[2 * n] != -1 && p[2 * n - 1] != -1){

            if(p[2 * n - 1] > p[2 * n] && p[2 * n] != -1)
                ans = p[2 * n];
            else
                ans = p[2 * n - 1];

        }else if(p[2 * n] == -1){
            ans = p[2 * n - 1];
        }else
            ans = p[2 * n];

        printf("%I64d\n",ans);
    }
    return 0;
}


發佈了177 篇原創文章 · 獲贊 2 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章