zoukankan      html  css  js  c++  java
  • XHXJ's LIS (状态压缩最长上升子序列)

    题目链接:https://vjudge.net/contest/365059#problem/B

    题目大意:求区间L到R之间的数A满足A的的数位的最长递增序列的长度为K的数的个数。

    想法:

    需要用 nlogn 的求最长上升子序列的算法去解决这道题,但是不能直接硬套,需要对状态进行压缩一下。

    state状态维护的是前面上升子序列中出现的数字(二进制状态压缩),前面设状态为167(state为001100001),假设此时i=2,维护上升序列长度为3,应该把6变为2(此时state为001000011)

    127,最长上升子序列长度不变,但能让后面更多的数加进来。

    #pragma GCC optimize(3,"Ofast","inline")//O3优化
    #pragma GCC optimize(2)//O2优化
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    
    const double eps = 1e-10;
    const int maxn = 2e5 + 10;
    const int mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    LL L,R,k;
    int b[20];
    int len;
    LL mem[20][1100][15];
    
    int cal(int x) {
        int ans = 0;
        while (x) {
            ans += (x & 1);
            x >>= 1;
        }
        return ans;
    }
    
    int new_st(int st,int x) {
        for (int i = x;i <= 9;i++) {
            if (st & (1 << i)) {
                return (st ^ (1 << i)) | (1 << x);
            }
        }
        return st | (1 << x);
    }
    
    LL dfs(int cur,int st,bool f,bool g) {
        if (cur < 0)
            return cal(st) == k;
        if (!f && mem[cur][st][k] != -1)
            return mem[cur][st][k];
        int v = 9;
        if (f)
            v = b[cur];
        LL ans = 0;
        for (int i = 0;i <= v;i++) {
            ans += dfs(cur-1,(g && i == 0)?0:new_st(st,i),f && (i==v),g && (i == 0));
        }
        if (!f)
            mem[cur][st][k] = ans;
        return ans;
    }
    
    LL solve(LL x) {
        len = 0;
        while (x) {
            b[len++] = x % 10;
            x /= 10;
        }
        return dfs(len-1,0,1,1);
    }
    
    int main() {
        ios::sync_with_stdio(0);
        int T;
        cin >> T;
        int t = 1;
        memset(mem,-1, sizeof(mem));
        while (T--) {
            cin >> L >> R >> k;
            printf("Case #%d: %lld
    ",t++,solve(R)-solve(L-1));
        }
        return 0;
    }
  • 相关阅读:
    Microsoft.mshtml到底是什么?
    编译.NET程序自动产生版本号的规则
    VB.NET(2005)中关于dll调用的错误信息(转)
    C# RichTextBox控件 滚动条 自动移至 最后一条记录处
    如何刪除richtextbox最後一行
    Using Hudson for C++/CMake/CppUnit
    让开发自动化: 选择持续集成服务器
    C#加载窗体错误
    各种CI工具对比表
    用 Hudson 实现 Visual Studio (C++) 项目的 daily build
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12615277.html
Copyright © 2011-2022 走看看