zoukankan      html  css  js  c++  java
  • hdu_4352_XHXJ's LIS 数位DP/状态压缩

    给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的数有多少个

    /*
     * HDU 4352 XHXJ's LIS
     * 问L到R,各位数字组成的严格上升子序列的长度为K的个数。
     * 0<L<=R<263-1 and 1<=K<=10
     * 注意这里最长上升子序列的定义,和LIS是一样的,不要求是连续的
     * 所以用十位二进制表示0~9出现的情况,和O(nlogn)求LIS一样的方法进行更新
     * 
     */
    
    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    long long dp[25][1<<10][11];
    /*
     * dp[i][j][k]:i为当前进行到的数位,j状态压缩,为10个数字出现过的,其中1的个数就是最长上升子序列,k要求的上升子序列的长度
     */
    int K;
    int getnews(int x,int s)//更新新的状态
    {
        for(int i=x;i<10;i++)
            if(s&(1<<i))return (s^(1<<i))|(1<<x);
        return s|(1<<x);
    }
    int getnum(int s)//得到状态s中1的个数
    {
        int ret=0;
        while(s)
        {
            if(s&1)ret++;
            s>>=1;
        }
        return ret;
    }
    int bit[25];
    long long dfs(int pos,int s,bool e,bool z)//e是是不是上界标记,z是是不是前面的为0标记
    {
        if(pos==-1)return getnum(s)==K;
        if(!e &&dp[pos][s][K]!=-1)return dp[pos][s][K];
        long long ans=0;
        int end=e?bit[pos]:9;
        for(int i=0;i<=end;i++)
            ans+=dfs(pos-1,(z&&i==0)?0:getnews(i,s),e&&i==end,z&&(i==0));
        if(!e)dp[pos][s][K]=ans;
        return ans;
    }
    long long calc(long long n)
    {
        int len=0;
        while(n)
        {
            bit[len++]=n%10;
            n/=10;
        }
        return dfs(len-1,0,1,1);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T;
        long long l,r;
        memset(dp,-1,sizeof(dp));
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            scanf("%I64d%I64d%d",&l,&r,&K);
            printf("Case #%d: ",iCase);
            printf("%I64d
    ",calc(r)-calc(l-1));
        }
        return 0;
    }
  • 相关阅读:
    Laravel -- Excel 导入(import) (v2.1.0)
    mysql触发器
    支付宝和微信支付的坑
    php 中的引用(&)与foreach结合后的一个注意点
    oatu2.0认证原理(转)
    python3:time类
    python3练习:针对某一日期增加或减少时间、天数
    python:datetime类常用内容
    python3练习:计算日期差
    python3练习:涉及序列
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7578738.html
Copyright © 2011-2022 走看看