• 2019 HNCPC D Modulo Nine 数位DP


    题意

    给定长度n和m个限制(l,r),每一个限制的意义是(a_l imes a_{l+1} imes ... a_r = 0 quad mod 9)

    问有多少个满足所有条件且长度为n的10进制数(可以包含前导0)

    解题思路

    看到可以包含前导零的时候就想到了数位DP,但是比赛的时候没想出怎么记录状态来记忆化搜索。赛后听ljn讲了之后秒懂,我还是太菜了。

    模9为0可以分为3种情况:区间内9的个数大于等于1,0的个数大于等于1,或,3的个数+6的个数大于等于2,所以可以用4维数组(dp_{pos,last09,last36,second36})来记录状态

    (dp_{pos,last09,last36,second36}):pos表示当前枚举到了第几位,last09表示前一个0或9的下标,last36表示前一个3或6的下标,second36表示last36往前一个3或6的下标。

    然后按当前位为0或9,3或6,其他数字分类讨论,如果满足以pos为右端点的所有限制就继续转移。

    代码实现

    和叉姐的标称对拍没有出错,应该是对的吧

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn=1e5+5;
    const int mod=1e9+7;
    
    int n,m;
    int dp[55][55][55][55];//pos 09 36-1 36-2 
    vector<int>limit[55];
    ll dfs(int pos,int last_09,int last_36,int second_36){
    	if(pos==n+1)return 1;
    	if(dp[pos][last_09][last_36][second_36]!=-1)return dp[pos][last_09][last_36][second_36];
    	ll res=0;
    	for(int i=0;i<=9;i++){//枚举当前位
    		if(i==0 || i==9){
    			res=(res+dfs(pos+1,pos,last_36,second_36))%mod;
    		}
    		else if(i==3 || i==6){
    			bool flag=true; 
    			for(int l:limit[pos]){
    				if(last_09>=l)continue;
    				if(last_36>=l)continue;
    				flag=false;
    			}
    			if(flag)res=(res+dfs(pos+1,last_09,pos,last_36))%mod;
    		}
    		else{
    			bool flag=true;
    			for(int l:limit[pos]){
    				if(last_09>=l)continue;
    				if(second_36>=l)continue;
    				flag=false;
    			}
    			if(flag)res=(res+dfs(pos+1,last_09,last_36,second_36))%mod;
    		}
    	}
    	dp[pos][last_09][last_36][second_36]=res;
    	return res;
    }
    ll f(){
    	memset(dp,-1,sizeof(dp));
    	return dfs(1,-1,-1,-1);
    }
    int main()
    {
    	while(~scanf("%d %d",&n,&m)){
    		int l,r;
    		for(int i=1;i<=n;i++)limit[i].clear();
    		for(int i=1;i<=m;i++){
    			scanf("%d %d",&l,&r);
    			limit[r].push_back(l);
    		}
    		printf("%lld
    ",f());
    	}
        return 0;
    }
    
    
  • 相关阅读:
    微信JSSDK使用指南
    安装eclipse中html/jsp/xml editor插件以及改动html页面的字体
    OpenLayers 3+Geoserver+PostGIS实现点击查询
    编程算法
    javascript闭包具体解释
    网络安全基本概念
    Android 5.1 Settings源代码简要分析
    Linq 使用注意
    父类引用指向子类对象
    CPU使用率
  • 原文地址:https://www.cnblogs.com/zengzk/p/11445166.html
Copyright © 2020-2023  润新知