zoukankan      html  css  js  c++  java
  • bozoj3131: [Sdoi2013]淘金 数位dp

    链接

    https://www.lydsy.com/JudgeOnline/problem.php?id=3131

    思路

    1.

    函数值的素因子只有2、3、5、7
    由他们组成的状态不多,爆搜的时候即使搜不对也没关系,我们只是缩小范围而已
    所以不要管呢么多,搜到几万就差不多了,包含有可能的就行

    2.

    (f[i][j][0/1])表示后i位,乘积为j,n的i位>=k(枚举1-9)?1:0
    n的i位>k
    (f[i][j][1]+=f[i][j][1]+f[i][j][0])
    n的i位<k
    (f[i][j][0]+=f[i][j][1]+f[i][j][0])
    n的i位==k
    (f[i][j][1]+=f[i][j][1])
    (f[i][j][0]+=f[i][j][0])

    3.

    统计的时候,sort
    之后想象成二维数组,每一行都是单调的,所以只用头做比较,堆维护就可以
    单调队列没想过

    错误$$感叹

    dp调试真快啊,处理起来真恶心曹丹清

    代码

    #include <iostream>
    #include <queue>
    #include <map>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #define ll long long
    const ll N=5e5+7;
    const ll mod=1e9+7;
    using namespace std;
    ll n,k,val[N],c[N],js;
    ll f[15][N][2];
    ll A,B,jl[15];
    map<ll,ll> hasH;
    struct Pair {
    	ll first,second;
    	Pair() {}
    	Pair(ll a,ll b) :
    		first(a),second(b) {}
    };
    bool operator < (Pair a,Pair b) {
    	if(a.second==js+1) return 0;
    	if(b.second==js+1) return 1;
    	return c[a.first]*c[a.second]<c[b.first]*c[b.second];
    }
    bool cmp(ll a,ll b) {
    	return a>b;
    }
    priority_queue<Pair> q;
    int main() {
    	// freopen("a.in","r",stdin);
    	cin>>n>>k;
    	for(ll a=0,tmp_a=1;a<=39;++a,tmp_a*=2) {
    		if(tmp_a>n) break;
    		for(ll b=0,tmp_b=1;b<=25;++b,tmp_b*=3) {
    			if(tmp_a*tmp_b>n) break;
    			for(ll c=0,tmp_c=1;c<=17;++c,tmp_c*=5) {
    				if(tmp_a*tmp_b*tmp_c>n) break;
    				for(ll d=0,tmp_d=1;d<=14;++d,tmp_d*=7) {
    					if(tmp_a*tmp_b*tmp_c*tmp_d>n) break;
    					if(tmp_a*tmp_b*tmp_c*tmp_d==0) continue;
    					val[++js]=tmp_a*tmp_b*tmp_c*tmp_d;
    				}
    			}
    		}
    	}
    	sort(val+1,val+1+js);
    	js=unique(val+1,val+1+js)-val-1;
    	for(ll i=1;i<=js;++i) hasH[val[i]]=i;
    	ll AAA=0;
    	while(n) jl[++AAA]=n%10,n/=10;
    	f[0][1][1]=1;
    	for(ll i=1;i<=AAA;++i) {
    		for(ll j=1;j<=js;++j) {
    			for(ll k=1;k<=9;++k) {
    				if(val[j]%k==0) {
    					ll w=hasH[val[j]/k];
    					if(k==jl[i]) {
    						f[i][j][1]+=f[i-1][w][1];
    						f[i][j][0]+=f[i-1][w][0];
    					} else if(k<jl[i]) {
    						f[i][j][1]+=f[i-1][w][0]+f[i-1][w][1];
    					} else {
    						f[i][j][0]+=f[i-1][w][0]+f[i-1][w][1];
    					}
    				}
    			}
    		}
    	}
    	for(ll i=1;i<=js;++i) {
    		for(ll j=1;j<AAA;++j)
    			c[i]+=f[j][i][0]+f[j][i][1];
    		c[i]+=f[AAA][i][1];
    	}
    	sort(c+1,c+1+js,cmp);
    	for(ll i=1;i<=js;++i) q.push(Pair(i,1));
    	ll ans=0;
    	for(ll i=1;i<=k;++i) {
    		Pair x=q.top();
    		q.pop();
    		ans+=c[x.first]*c[x.second]%mod;
    		ans%=mod;
    		q.push(Pair(x.first,x.second+1));
    	}
    	cout<<ans<<"
    ";
    	return 0;
    }
    
  • 相关阅读:
    二项堆(三)之 Java的实现
    二项堆(二)之 C++的实现
    二项堆(一)之 图文解析 和 C语言的实现
    斜堆(三)之 Java的实现
    斜堆(二)之 C++的实现
    斜堆(一)之 C语言的实现
    左倾堆(三)之 Java的实现
    左倾堆(二)之 C++的实现
    左倾堆(一)之 图文解析 和 C语言的实现
    二叉堆(三)之 Java的实现
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10415679.html
Copyright © 2011-2022 走看看