zoukankan      html  css  js  c++  java
  • 数位DP模板

    https://www.luogu.com.cn/problem/P2602

    挺简单 的其实,板子题

    真实的模板

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int len,a[2000];
    ll l,r,dp[20][15][25][25][20];
    
    ll dfs(int pos,int pre,ll st,ll sum,int d,int lead,int limit)
    //pos搜到的位置
    //pre前一位数
    //st当前公差最大差值
    //sum整个数字的最大价值
    //d共差
    //lead判断是否有前导0
    //limit判断是否有最高位限制
    
    {
        if(pos>len) return sum;//dp结束 
        //记录状态(计划搜索)
        //注意d有负数,最小可以到-9,所以记录时数组下标是d+10 
        if((dp[pos][pre][st][sum][d+10]!=-1&&(!limit)&&(!lead))) return dp[pos][pre][st][sum][d+10]; 
        ll ret=0;
        int res=limit?a[len-pos+1]:9;//最高位最大值 
        for(int i=0;i<=res;i++)
        {
            //有前导0且这位也是前导0,一切不变只有位数变化 
            if((!i)&&lead) ret+=dfs(pos+1,0,0,0,-38,1,limit&&(i==res));
            //有前导0但这位不是前导0(这位是数字的最高位)开始有前一位,一个数形成等差数列 
            else if(i&&lead) ret+=dfs(pos+1,i,1,1,-38,0,limit&&(i==res));
            //之前刚搜到1位还没有共差,两位数形成等差数列,记录共差 
            else if(d<-9) ret+=dfs(pos+1,i,2ll,2ll,i-pre,0,limit&&(i==res));
            //搜到2位以后,共差若与前两位相同当前等差数列长度增加,若公差变化则更新整个数字的最大价值,等差数列长度又变为2 
            else if(d>=-9) ret+=dfs(pos+1,i,(i-pre==d)?st+1:2,max(sum,(i-pre==d)?st+1:2),(i-pre==d)?d:i-pre,0,limit&&(i==res));
        }
        //没有前导0和最高限制时可以直接记录当前dp值以便下次搜到同样的情况可以直接使用。 
        return (!limit&&!lead)?dp[pos][pre][st][sum][d+10]=ret:ret;
    }
    
    
    
    ll part(ll x)
    {
        len=0;
        while(x) a[++len]=x%10,x/=10;
        memset(dp,-1,sizeof dp);
        return dfs(1,0,0,0,-38,1,1);//-38是随便赋的其实赋成-10就行了…… 
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld",&l,&r);
            //l是0的时候要特别注意!
            printf("%lld
    ",l?(part(r)-part(l-1)):(part(r)-part(l)+1));
        }
        return 0;
    }
    

      

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn = 100+11;
    ll dp[maxn][maxn];//第i位置的x有dp[i][][x]个
    ll list[maxn];
    
    ll dfs(int cur,int up,int lead,int val,ll sum) { //cur位置,用了sum个数字 ,lead ==1有前导0
    	if(cur == 0) return sum;
    	if(!up&&lead&&dp[cur][sum] != -1) return dp[cur][sum];
    	int lim = 9;
    	if(up) lim = list[cur];
    	ll cns =0 ;
    
    	for(int i=0; i<=lim; i++) {
    		cns += dfs(cur-1,up && (i == lim),i || lead,val,sum + ((i == val) && (i || lead)));
    	}
    
    	if(!up && lead) dp[cur][sum] = cns;
    	return cns;
    }
    
    
    vector<ll>ins;
    
    int cal(ll n) {
    
    
    
    	ll cnt =0;
    
    	while(n) {
    		list[++cnt] = n%10;
    		n /= 10;
    	}
    	for(int i=0; i<10; i++) {
    		memset(dp,-1,sizeof(dp));
    		ins.push_back(dfs(cnt,1,0,i,0));
    	}
    
    
    }
    
    int main() {
    
    	ll l,r;
    	scanf("%lld %lld",&l,&r);
    	cal(r);
    	cal(l-1);
    
    	for(int i=0; i<ins.size()-10; i++) {
    		printf("%lld",ins[i] - ins[i+10]);
    		if(ins.size() - 9 == i) printf("
    ");
    		else printf(" ");
    	}
    	//printf("
    ");
    
    	return 0;
    }





    寻找真正的热爱
  • 相关阅读:
    ExtJs错误总结
    Java中的基本类型和引用类型(未完)
    【转】JavaScript中的全局变量与局部变量
    地理信息技术在现场项目的应用浅析
    vector的二分查找算法
    Linux命令
    封装 libmemcached
    Linux + boost + libmemcached + jsoncpp + mysql 配置
    SQL字符串处理函数大全(转)
    vector 排序方法sort的使用
  • 原文地址:https://www.cnblogs.com/lesning/p/13641994.html
Copyright © 2011-2022 走看看