zoukankan      html  css  js  c++  java
  • HDU 3092 Least common multiple 01背包

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=3092

    Least common multiple

    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 65536/65536 K (Java/Others)
    #### 问题描述 > Partychen like to do mathematical problems. One day, when he was doing on a least common multiple(LCM) problem, he suddenly thought of a very interesting question: if given a number of S, and we divided S into some numbers , then what is the largest LCM of these numbers? partychen thought this problems for a long time but with no result, so he turned to you for help! > Since the answer can very big,you should give the answer modulo M. #### 输入 > There are many groups of test case.On each test case only two integers S( 0 < S <= 3000) and M( 2<=M<=10000) as mentioned above. #### 输出 > Output the largest LCM modulo M of given S. ####样例输入 > 6 23

    样例输出

    6

    题意

    给你一个n,求把n拆成若干个数的和,要求这些数的最小公倍数最大。最后输出%M.

    题解

    由于最大公倍数会爆,无法直接维护,所以我们可以通过取对数的方式,得到大小,确定转移方向,然后利用这个去维护最优解。

    这道题需要用到两个贪心策略:
    1、只选质数(或质数的幂)(22*3=12,还不如22+3=7。)
    2、每个质数只选一个(如果你拆出39=3+9+27,明显,只有27是有用的。。)

    然后就可以转换成01背包求解了(贪心策略2决定了这是01背包!不是完全背包)

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<sstream>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=3333;
    
    double dp[maxn];
    LL ans[maxn];
    
    bool pri[maxn];
    VI arr;
    void pre() {
        clr(pri,0);
        for(int i=2; i*i<maxn; i++) {
            if(!pri[i]) {
                for(int j=i*i; j<maxn; j+=i) {
                    pri[j]=true;
                }
            }
        }
        for(int i=2; i<maxn; i++) if(!pri[i]) arr.pb(i);
    }
    
    int main() {
        pre();
        int S,M;
        while(scf("%d%d",&S,&M)==2) {
            clr(dp,0);
            double Ma=-1;
            LL last=1;
            for(int i=0; i<=S; i++) ans[i]=1;
            //01背包
            for(int i=0; arr[i]<=S; i++) {
                for(int j=S; j>=arr[i]; j--) {
                    for(int k=arr[i]; k<=j; k*=arr[i]) {
                        if(dp[j]<dp[j-k]+log10(k)) {
                            dp[j]=dp[j-k]+log10(k);
                            ans[j]=ans[j-k]*k%M;
                        }
                    }
                    if(Ma<dp[j]+eps) {
                        Ma=dp[j];
                        last=ans[j];
                    }
                }
            }
            prf("%I64d
    ",last);
        }
    
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    浅谈HashMap的内部实现
    浅谈Java的集合体系
    如何通过注解Bean类来封装SQL插入语句
    谈一谈垃圾回收器
    万物皆对象
    关于枚举
    Servlet向客户端发送中文数据的编码情况
    "流"派家族,一脉相承
    个人简历用HTML编写
    get和post的区别
  • 原文地址:https://www.cnblogs.com/fenice/p/5923534.html
Copyright © 2011-2022 走看看