zoukankan      html  css  js  c++  java
  • [SDOI2013]淘金

    题目

    爆搜毁所有,当然(%%)能过的(dalao),反正(juruo)那个三四十分够了

    做法

    (c[i]=sumlimits_{j} f[j]=i),这题直接动规更简单,(dp[i][j][0/1])从低到高为前(i)位,乘积为(j),是否顶着上界

    My complete code

    #include<bits/stdc++.h>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long LL;
    const LL maxn=160100,p=1e9+7;
    LL tmpl,tot,bl,n,K;
    LL c[6000000],tmp[6000000],f[20][maxn][2],a[20],b[6000000];
    map<LL,LL> pos;
    inline void Solve(LL x){
        tot=0;
        LL Up(1);
        while(x) a[++tot]=x%10, x/=10, Up*=9;
        Up/=9; Up*=a[tot];
        tmp[tmpl=1]=1;
        for(LL i=1;i<=tot;++i){
            bl=0;
            for(LL j=1;j<=9;++j){
                for(LL k=1;k<=tmpl;++k)
                    b[++bl]=tmp[k]*j;
            }
            sort(b+1,b+1+bl); bl=unique(b+1,b+1+bl)-1-b;
            tmpl=bl;
            for(LL j=1;j<=bl;++j) tmp[j]=b[j];
        }
        LL T(tmpl);
    	for(LL i=1;i<=T;++i) if(tmp[i]<=Up) pos[tmp[i]]=i;else --T;
    	tmpl=T;
        for(LL i=1;i<=9;++i) f[1][pos[i]][i>a[1]]=1;
        for(LL i=2;i<=tot;++i) for(LL j=1;j<=tmpl;++j) for(LL k=1;k<=9;++k){
            LL val=tmp[j];
    		if(val%k!=0) continue;
            LL h=pos[val/k];
            if(k<a[i]) 
    		    f[i][j][0]+=f[i-1][h][0]+f[i-1][h][1];
            else if(k>a[i])
                f[i][j][1]+=f[i-1][h][0]+f[i-1][h][1];
            else
    		    f[i][j][0]+=f[i-1][h][0],
                f[i][j][1]+=f[i-1][h][1];
        }
        for(LL j=1;j<=tmpl;++j) for(LL i=1;i<=tot;++i)
            c[j]+=f[i][j][0]+(i==tot?0:f[i][j][1]);
    }
    struct heap{
        LL i,j;
        bool operator < (const heap &x)const{
            return c[i]*c[j]<c[x.i]*c[x.j];
        }
    };priority_queue<heap> que;
    int main(){
        cin>>n>>K;
        Solve(n);
        sort(c+1,c+1+tmpl);
        for(LL i=1;i<=tmpl;++i) que.push((heap){i,tmpl});
        LL ans(0);
        while(K--&&que.size()){
            heap tmp=que.top(); que.pop();
            (ans+=c[tmp.i]*c[tmp.j])%=p;
            if(tmp.j==1) continue;
            que.push((heap){tmp.i,tmp.j-1});
        }cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    js函数调用模式
    js闭包和回调
    js原型
    oracle sql优化笔记
    shell脚本学习
    程序与资源管理
    vi/vim学习
    压缩和解压缩
    用户及用户组
    万用字符和特殊字符
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10452250.html
Copyright © 2011-2022 走看看