zoukankan      html  css  js  c++  java
  • 【YBTOJ】【数位DP】 魔法数字

    魔法数字

    还是很麻烦的一道题……

    题解

    先证明一个结论:

    (p=operatorname{lcm}(p_1,p_2,cdots,p_n)) ,则有(forall xin N ,iin[1,n], (xoperatorname{mod} p)operatorname{mod} p_i = xoperatorname{mod}p_i) .

    证明:

    因为(p=operatorname{lcm}(p_1,p_2,cdots,p_n)),则有(p = kcdot p_i).

    (x=scdot p+r = (kcdot s)p_i+r)

    证毕。

    应用:对于 (forall x) ,求 (xoperatorname{mod}{p_{1cdots n}}) ,可以求出 (x operatorname{mod} operatorname{lcm}(p)) ,再求其模。

    对于此题:要求此数对于 (1cdots9) 的余数,可以求其与 (operatorname{lcm}(1cdots 9)) 的余数,再单独取余。

    题目中还要求是否出现过某数,可以使用状压来解决。

    则dp状态:

    (dp(pos,st,lft)) 表示:

    • 填到第 (pos) 位.
    • 是否出现过某数的状态为 (st) .
    • 取余后结果为 (lft) .

    如果这样设计的话,空间复杂度是(O(18 imes 512 imes 2520) approx O(2e7)).

    考虑如何优化这个过程:

    如果末位是(0)(5),则它一定是(5)的倍数。

    这样,就不需要考虑(5)的影响。其(operatorname{lcm})变为(504).

    代码

    #include <bits/stdc++.h>
    #define fo(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    const int INF = 0x3f3f3f3f,N = 1e5+5;
    typedef long long ll;
    typedef unsigned long long ull;
    inline ll read(){
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9'))ch=c,c=getchar();
    	while(c>='0'&&c<='9')ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    ll l,r;int k;
    ll dp[20][520][510];
    int num[20];
    ll dfs(int pos,int st,int lft,short lst,bool lim){		
    //	printf("  dfs(%d)
    ",pos);
    	if(!pos){
    //		printf(" ans add(%d,%d,%d,%d)
    ",st,lft,lst,lim);
    		int cnt = 0;
    		for(int i = 1 ; i <= 9 ; i ++)
    			if(i != 5 && st & (1<<(i-1)) && !(lft % i)) cnt ++;
    		if(st & (1<<4) && (lst == 5 || !lst)) cnt ++;
    //		puts(cnt >= k ? "YES" : "NO");
    		return cnt >= k;
    	}
    	if(~dp[pos][st][lft] && !lim) return dp[pos][st][lft];
    	int mx = lim ? num[pos] : 9;
    	ll ret = 0;
    	for(int i = 0 ; i <= mx ; i ++)
    		ret += dfs(pos-1,!i ? st : st | (1<<(i-1)) , (lft*10+i)%504 , i , lim && i==mx);
    	if(!lim) dp[pos][st][lft] = ret;
    	return ret;
    	
    }
    inline ll solve(ll x){
    //	printf(" ans(%lld) = ",x);
    	int cnt = 0;
    	while(x)
    		num[++cnt] = x % 10,
    		x /= 10;
    //	printf("%lld
    ",dfs(cnt,0,0,0,1));
    //	puts("");puts("");;
    	return dfs(cnt,0,0,0,1);
    }
    signed main(){
    	memset(dp,-1,sizeof(dp));
    	k = read() , l = read() , r = read();
    	printf("%lld",solve(r)-solve(l-1));
    	return 0;
    } 
    
  • 相关阅读:
    centos7安装nginx的两种方法
    centos7 搭建keepalived+Nginx+tomcat
    Linux下Nginx+Tomcat负载均衡和动静分离配置要点
    Tomcat结合Apache、Nginx实现高性能的web服务器
    centos7安装jdk+tomcat+nginx+mysql
    python3 密码生成器
    如何处理Tomcat日志catalina.out日志文件过大的问题
    Tomcat关闭日志catalina.out
    tomcat 启动项目时出现 ZipException: error in opening zip file
    [科普]MinGW vs MinGW-W64及其它(比较有意思,来自mingw吧)
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15261220.html
Copyright © 2011-2022 走看看