HDU ~ 4352 ~ XHXJ's LIS (数位DP + LIS + 状压)

题意

[L,R]区间内,各位数字组成的LIS(严格上升)长度为K的个数?

思路

如果还按照记忆化搜索的方式来写,那么我们过程中需要维护的是选了一个数字之后LIS的变化,我们应该怎么维护呢?

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL L, R, K, dp[20][1<<10][15];
string num;
int update(int x, int state)
{
    for (int i = x; i <= 9; i++)
        if (state&(1<<i)) return (state^(1<<i))|(1<<x);
    return state|(1<<x);
}
LL dfs(int pos, int state, bool limit, bool allzero)
{
    if (pos == -1) return __builtin_popcount(state) == K;
    if (!limit && dp[pos][state][K] != -1) return dp[pos][state][K];
    LL ans = 0;
    int E = limit?num[pos]-'0':9;
    for (int i = 0; i <= E; i++)
        ans += dfs(pos-1, (allzero&&(i==0)) ? 0 : update(i, state), limit&&(i==E), allzero&&(i==0));
    if (!limit) dp[pos][state][K] = ans;
    return ans;
}
LL solve(LL x)
{
    num = to_string(x); reverse(num.begin(), num.end());
    return dfs(num.size()-1, 0, 1, 1);
}
int main()
{
    memset(dp, -1, sizeof(dp));
    int T, CASE = 1; scanf("%d", &T);
    while (T--)
    {
        scanf("%lld%lld%lld", &L, &R, &K);
        printf("Case #%d: %lld\n", CASE++, solve(R)-solve(L-1));
    }
    return 0;
}
/*
1
123 321 2
*/



猜你喜欢

转载自blog.csdn.net/zscdst/article/details/81071870
今日推荐