zoukankan      html  css  js  c++  java
  • LuoguP3303 「SDOI2013」淘金

    LuoguP3303 「SDOI2013」淘金

    哇简单DP题!

    这都能评黑?

    考虑对于每个 (x)​ ,求出 (f(i)=x)​ 的 (i)​ 的个数,使用数位 DP ,由于 (x) 的质因子只可能有 2,3,5,7 四种,所以 (x) 的范围不会太大,数位 DP 记录已用格子数和每个质因子的指数即可。记其为 (c(x))

    然后对 (c(x)) 从大到小排序,对每个点记录指针表示最大的可用点,用堆维护即可。

    #include<bits/stdc++.h>
    #define fo(i,a,b) for(int i=a;i<=b;++i)
    #define fd(i,a,b) for(int i=a;i>=b;--i)
    #include <ext/pb_ds/priority_queue.hpp>
    using namespace __gnu_pbds;
    #define ll long long
    using namespace std;
    const int N=1e5+10;
    const int M=5e6+10;
    const int mod=1e9+7;
    ll n,f[20][41][30][20][20],c[M],ans;
    int k,a[20],s1,s2,s3,s4,cnt;
    bool flag=0;
    struct node{
    	ll x,y;
    	inline bool operator<(const node &o)const{
    		return x * c[y] < o.x * c[o.y];
    	}
    };
    __gnu_pbds ::priority_queue< node > d;
    bool cmp(ll a,ll b){return a>b;}
    void add(ll &a,ll b){a=(a+b>=mod?a+b-mod:a+b);}
    void trans(int t,int S1,int S2,int S3,int S4,int num,ll s,int type=1){
    	while(!(num%2))++S1,num/=2;
    	while(!(num%3))++S2,num/=3;
    	while(!(num%5))++S3,num/=5;
    	while(!(num%7))++S4,num/=7;
    	if(type==-1){
    		s1=S1;s2=S2;s3=S3;s4=S4;
    		return;
    	}
    	f[t][S1][S2][S3][S4]+=s;
    }
    void dp(){
    	int m=0;
    	for(ll i=n;i;i/=10)a[++m]=i%10;
    	fo(i,1,a[m]-1)trans(m,0,0,0,0,i,1);
    	flag|=(a[m]==0);
    	if(!flag)trans(m,0,0,0,0,a[m],1,-1);
    	fd(i,m-1,1){
    		fo(j1,0,39){
    			fo(j2,0,25){
    				fo(j3,0,17){
    					fo(j4,0,14){
    						ll tmp=f[i+1][j1][j2][j3][j4];
    						if(!tmp)continue;
    						fo(l,1,9){
    							trans(i,j1,j2,j3,j4,l,tmp);
    						}
    					}
    				}
    			}
    		}
    		fo(l,1,9)
    			trans(i,0,0,0,0,l,1);
    		if(!flag)
    			fo(l,1,a[i]-1)
    				trans(i,s1,s2,s3,s4,l,1);
    		flag|=(a[i]==0);
    		if(!flag)trans(1,s1,s2,s3,s4,a[i],1,-1);
    	}
    	if(!flag)trans(1,s1,s2,s3,s4,1,1);
    	fo(j1,0,39){
    		fo(j2,0,25){
    			fo(j3,0,17){
    				fo(j4,0,14){
    					ll tmp=f[1][j1][j2][j3][j4];
    					if(tmp){
    						c[++cnt]=tmp;
    					}
    				}
    			}
    		}
    	}
    }
    void solve(){
    	sort(c+1,c+cnt+1,cmp);
    //	fo(i,1,cnt)printf("%d ",c[i]);
    //	printf("
    ");
    	fo(i,1,cnt)
    		d.push((node){c[i],1});
    	k=min((ll)k,(ll)cnt*cnt);
    	fo(i,1,k){
    		node a=d.top();
    		d.pop();
    		add(ans,a.x * c[a.y] % mod);
    		if(a.y<cnt){
    			d.push((node){a.x,a.y+1});
    		}
    	}
    }
    int main(){
    	scanf("%lld%d",&n,&k);
    	dp();
    	solve();
    	printf("%lld
    ",ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/Kelvin2005/p/15185180.html
Copyright © 2011-2022 走看看