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;
    }
    
  • 相关阅读:
    每天一个linux命令(22):find 命令的参数详解
    在gitlab中创建项目后如何用git初始上传项目
    TensorBoard可视化
    docker CMD 和 ENTRYPOINT 区别
    django 项目开发及部署遇到的坑
    nginx + uwsgi 部署django项目
    centos7 追加python3 + 使用pip + virtualenv
    docker 常用命令
    Django+celery+rabbitmq实现邮件发送
    web框架链接
  • 原文地址:https://www.cnblogs.com/Kelvin2005/p/15185180.html
Copyright © 2011-2022 走看看