51nod1623完美消除 【数位dp】

链接:http://www.51nod.com/onlineJudge/submitDetail.html#!judgeId=108709

分析:在枚举每一位观察到 212需要3次,121只要2次,我们可以发现若新枚举的数在前面的一个递增状态没出现过,操作数+1。

比如:前面的状态为“1 2 3 4 5 6” 再加入5时 状态变为“1 2 3 4 5”, 因为后面如果再加入6就会形成“12345656” 操作数还是要+1. 


代码:


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 21
#define Mm 1026
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CLRS(a,b,Size) memset((a),(b),sizeof((a[0]))*(Size+1))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int a[Mn];
int vis[Mn][Mm][Mn],K;
ll dp[Mn][Mm][Mn];
int s[12],p[12];
ll cal(int len,int pre,int isM,int k) {
    if(len==0) return k==K;
    if(!isM) {
        if(vis[len][pre][k]) return dp[len][pre][k];
        vis[len][pre][k]=1;
        for(int i=0;i<=9;i++)
            if(pre&s[i]) dp[len][pre][k]+=cal(len-1,pre&p[i],0,k);
            else dp[len][pre][k]+=cal(len-1,(pre&p[i])|s[i],0,k+(i!=0));
        return dp[len][pre][k];
    } else {
        ll re=0;
        for(int i=0;i<=a[len];i++)
            if(pre&s[i]) re+=cal(len-1,pre&p[i],i==a[len],k);
            else re+=cal(len-1,(pre&p[i])|s[i],i==a[len],k+(i!=0));
        return re;
    }
}
ll solve(ll x) {
    int cnt=0;
    while(x) {
        a[++cnt]=x%10;
        x/=10;
    }
    return cal(cnt,0,1,0);
}
int main() {
    CLR(vis,0);
    CLR(dp,0);
    s[0]=p[0]=0;
    for(int i=1;i<=9;i++) {
        s[i]=1<<(i-1);p[i]=(1<<i)-1;
    }
    ll l,r;
    scanf("%lld%lld%d",&l,&r,&K);
    printf("%lld\n",solve(r)-solve(l-1));
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值