zoukankan      html  css  js  c++  java
  • 数位dp:bzoj1799

    一开始没有想到枚举所有模数求解,卡了很久。

    写法见代码注释。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<stack>
    #include<map>
    #include<vector>
    #include<queue>
    #include<set>
    #include<iomanip>
    #include<cctype> 
    #include<ctime>
    using namespace std;
    #define ll long long
    #define edl putchar('
    ')
    #define sscc ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define FOR(i,a,b) for(int i=a;i<=b;i++)
    #define ROF(i,a,b) for(int i=a;i>=b;i--)
    #define FORLL(i,a,b) for(ll i=a;i<=b;i++)
    #define ROFLL(i,a,b) for(ll i=a;i>=b;i--)
    #define mst(a) memset(a,0,sizeof(a))
    #define mstn(a,n) memset(a,n,sizeof(a))
    #define zero(x)(((x)>0?(x):-(x))<eps)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int month[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    const int MAXN=1e5+5;
    const int INF=1<<30;
    const long long mod=1e9+7;
    const double eps=1e-8;
    ll dp[25][170][170];
    /*dp数组记录答案,第一维为第几位,第二维为当前数字模p的结果,第三维为数位和*/ 
    int a[25],p,vis[25][170][170];
    /*a数组记录每一位的值,p为模数,vis数组对应dp,代表在模p时是否访问过*/ 
    ll dfs(int pos,int m,int sta,int limit)/*第几位 模后的数 数位和 上限*/ 
    {
    	if(pos==0)
    		return sta==0&&m%p==0;
    	if(!limit&&vis[pos][m][sta]==p)
    	{
    		return dp[pos][m][sta];
    	}
    	vis[pos][m][sta]=p;/*更新vis访问标记*/ 
    	int up=limit?a[pos]:9;
    	ll ans=0;
    	FOR(i,0,up)
    	{
    		if(sta>=i)
    		ans+=dfs(pos-1,(m*10+i)%p,sta-i,limit&&i==up);
    		/*由于枚举p时数位和是固定的,所以直接用p减去数位和*/ 
    	}
    	if(!limit)
    		dp[pos][m][sta]=ans;
    	return ans;
    }
    ll solve(ll x)
    {
        int pos=0,t;
        while(x)
        {
            a[++pos]=x%10;
            x/=10;
        }
        a[pos+1]=0;
        t=pos*9;
        ll ans=0;
        FOR(i,1,t)
        p=i,ans+=dfs(pos,0,i,1);
        return ans;
    }
    int main()
    {
        ll n,m;
        {
        	scanf("%lld%lld",&n,&m);
        	mst(vis); 
            n=solve(n-1);
            mst(vis);/*每次处理都要对vis初始化*/ 
            m=solve(m);
    		printf("%lld
    ",m-n);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Session Cookie介绍和使用
    Java 设计模式(概述)
    Java-JSON 解析
    Java Fileupload
    docker执行mysql容器修改用户权限
    分布式事务Seata
    idea配置git_2
    idea配置注释
    idea配置git的ssh
    远程阿里云镜像问题
  • 原文地址:https://www.cnblogs.com/qq936584671/p/9688688.html
Copyright © 2011-2022 走看看