• bzoj1799: [Ahoi2009]self 同类分布


    数位dp

    先从1到162枚举各位数之和

    s[i][j][k][l]表示i位数,第一位小于等于j,当前各位数字和为k,当前取模余数为l的方案数

    然后脑补一下转移就行了

    详见代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #define ll long long
    
    using namespace std;
    ll P;
    int bin[20];
    bool vis[20][180][180];
    ll s[20][10][180][180];
    
    ll f(int n,int t,int sum,int mod);
    void solve(int n,int sum,int mod){
    	if (n<1) return;
    	if (vis[n][sum][mod]) return;
    	vis[n][sum][mod]=1;
    	for (int i=0;i<10;++i)
    		s[n][i][sum][mod]=f(n-1,9,sum-i,(mod-bin[n]*i%P+P)%P);
    	for (int i=1;i<10;++i) s[n][i][sum][mod]+=s[n][i-1][sum][mod];
    }
    ll f(int n,int t,int sum,int mod){
    	if (sum<0||n*9<sum||t<0) return 0;
    	if (n<1) return mod==0;
    	solve(n,sum,mod);
    	return s[n][t][sum][mod];
    }
    
    int a[21],b[21],len0,len1;
    int main(){
    	ll L,R;
    	scanf("%lld%lld",&L,&R);++R;
    	for (len0=0;L;L/=10) a[++len0]=L%10;
    	for (len1=0;R;R/=10) b[++len1]=R%10;
    	bin[1]=1;
    	ll ans=0;
    	for (P=1;P<=len1*9;++P){
    		for (int i=2;i<=len1;++i) bin[i]=bin[i-1]*10%P;
    		ll ans0,ans1;
    		memset(vis,0,sizeof(vis));
    		for (int k=0;k<2;++k){
    			swap(ans0,ans1);ans0=0;
    			for (int i=1;i<=max(len0,len1);++i) swap(a[i],b[i]);
    			swap(len0,len1);
    			int now=P,nowmod=0;
    			for (int i=len0;i;--i){
    				ans0+=f(i,a[i]-1,now,nowmod);
    				now-=a[i];nowmod=(nowmod-a[i]*bin[i]%P+P)%P;
    			}
    		}
    		ans+=ans1-ans0;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

    代码写的好乱……

  • 相关阅读:
    分享我的2014年3月unity3d面试题与参考答案(转)
    Unity3D 面试ABC
    MiniJson解释Json字符串
    Unity3D研究之支持中文与本地文件的读取写入(转)
    unity3d--NGUI制作中文字体
    吊炸天之十步完全理解SQL
    mysql主从同步碰到的问题
    Redis 安装碰到问题
    在Centos系统下使用命令安装gnome图形界面程序
    centos7 网络问题
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5129644.html
Copyright © 2020-2023  润新知