zoukankan      html  css  js  c++  java
  • AW311 月之谜

    题目地址


    状态设计:

    • f[当前位数][之前每一位的和][当前余数][当前位数字是否与原数相同].
    • 转移方式是通过余数的结构持久保存和对初始状态的特殊判定实现的.
    • 在代码中之所以需要分开进行转移,是由于需要在保证当前数字在范围内的同时又需要对一些高位小但其他位大的数字进行转移。为了兼顾两种情况,将初始状态设为需要判定才能转移即可.

    易错点:

    • 需要对取模运算的深刻认识.
    • 需要对数位DP转移方式的深刻认识.

    一句话总结:

    • 完美的线性递推结构与合理的状态设计思想.

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ll long long
    using namespace std;
    ll f[25][190][190][2],dight[25],dightTop=0;
    ll calc(ll num,int mod){
    	memset(f,0,sizeof(f));
    	dightTop=0;
    	while(num){
    		dight[++dightTop]=num%10;
    		num/=10;
    	}
    	f[dightTop+1][0][0][1]=1;
    	for(int i=dightTop+1;i>1;i--){
    		for(int j=0;j<=mod;j++){
    			for(int k=0;k<mod;k++){
    				if(!f[i][j][k][0]&&!f[i][j][k][1])continue;
    				for(int p=0;p<=9;p++){
    					f[i-1][j+p][(k*10+p)%mod][0]+=f[i][j][k][0];
    					if(p==dight[i-1])f[i-1][j+p][(k*10+p)%mod][1]+=f[i][j][k][1];
    					else if(p<dight[i-1])f[i-1][j+p][(k*10+p)%mod][0]+=f[i][j][k][1];		
    				}
    			}
    		}
    	}
    	return f[1][mod][0][0]+f[1][mod][0][1];
    }
    int main(){
    	ll l,r;
    	scanf("%lld%lld",&l,&r);
    	ll ans=0,dightNumber=9*21;
    	for(int i=1;i<dightNumber;i++){
    		ans+=calc(r,i)-calc(l-1,i);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
  • 相关阅读:
    最近的一些心理活动
    object_c函数多个返回值
    nslayoutConstraint
    判断一些常用的东西
    color 的一些处理
    最近的心理活动
    加载不同的nib文件
    Be a person
    按钮居左显示
    SQLite错误码
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680577.html
Copyright © 2011-2022 走看看