HDU

#define xhxj (Xin Hang senior sister(学姐)) 
If you do not know xhxj, then carefully reading the entire description is very important. 
As the strongest fighting force in UESTC, xhxj grew up in Jintang, a border town of Chengdu. 
Like many god cattles, xhxj has a legendary life: 
2010.04, had not yet begun to learn the algorithm, xhxj won the second prize in the university contest. And in this fall, xhxj got one gold medal and one silver medal of regional contest. In the next year's summer, xhxj was invited to Beijing to attend the astar onsite. A few months later, xhxj got two gold medals and was also qualified for world's final. However, xhxj was defeated by zhymaoiing in the competition that determined who would go to the world's final(there is only one team for every university to send to the world's final) .Now, xhxj is much more stronger than ever,and she will go to the dreaming country to compete in TCO final. 
As you see, xhxj always keeps a short hair(reasons unknown), so she looks like a boy( I will not tell you she is actually a lovely girl), wearing yellow T-shirt. When she is not talking, her round face feels very lovely, attracting others to touch her face gently。Unlike God Luo's, another UESTC god cattle who has cool and noble charm, xhxj is quite approachable, lively, clever. On the other hand,xhxj is very sensitive to the beautiful properties, "this problem has a very good properties",she always said that after ACing a very hard problem. She often helps in finding solutions, even though she is not good at the problems of that type. 
Xhxj loves many games such as,Dota, ocg, mahjong, Starcraft 2, Diablo 3.etc,if you can beat her in any game above, you will get her admire and become a god cattle. She is very concerned with her younger schoolfellows, if she saw someone on a DOTA platform, she would say: "Why do not you go to improve your programming skill". When she receives sincere compliments from others, she would say modestly: "Please don’t flatter at me.(Please don't black)."As she will graduate after no more than one year, xhxj also wants to fall in love. However, the man in her dreams has not yet appeared, so she now prefers girls. 
Another hobby of xhxj is yy(speculation) some magical problems to discover the special properties. For example, when she see a number, she would think whether the digits of a number are strictly increasing. If you consider the number as a string and can get a longest strictly increasing subsequence the length of which is equal to k, the power of this number is k.. It is very simple to determine a single number’s power, but is it also easy to solve this problem with the numbers within an interval? xhxj has a little tired,she want a god cattle to help her solve this problem,the problem is: Determine how many numbers have the power value k in [L,R] in O(1)time. 
For the first one to solve this problem,xhxj will upgrade 20 favorability rate。

InputFirst a integer T(T<=10000),then T lines follow, every line has three positive integer L,R,K.( 
0<L<=R<2 63-1 and 1<=K<=10).OutputFor each query, print "Case #t: ans" in a line, in which t is the number of the test case starting from 1 and ans is the answer.Sample Input

1
123 321 2

Sample Output

Case #1: 139 

题意:
1.If you consider the number as a string and can get a longest strictly increasing subsequence the length of which is equal to k, the power of this number is k.
2. Determine how many numbers have the power value k in [L,R] in O(1)time. 
思路:
dp[pos][sta][k]
pos:搜索到第几位
sta:之前的最长上升子序列的状态。
k:就是输入的那个k

此题的难点就在于中间的那一维--sta。
sta的二进制每一位,都对应了数位上的一个数字。
举例来说:如果sta按照数字13425来更新。
首先遇到1,变成 0100000000 (或者0000000010,其实这是完全一样的,只要保证不同状态的sta不一样就行了)
然后遇到3,很明显,之前没有比3更大的数字,然后变成0101000000

遇到4,sta变成0101100000

在这里打断一下,不能看出,sta中1的个数,就是LIS的长度。

然后遇到2,这时大于等于2的有一个3.于是把3的二进制1交给2,sta变成0110100000
为什么这么做?????
首先我们知道,这样做绝不会改变1的个数,如果之前出现过2,那么sta就不会变化,否则就把之后最近的那个1挪到当前位置。
然后再看这4个数字:1342
如果之后出现的数字有比这四个数字都大的,那么之前究竟是1243还是1342都对后方的更新没有影响了。
就如同例子中的5,它只需知道,在之前出现的数字中最大的没有自己大就行了,因为只要这样,就可把5位置的0变成1。
注意:如果有多种状态,( 1243 ,1342 ),只要对后续影响相同,就可以看做同一种状态。

如果之后出现的数字没有比这四个数都大的,那么还是不会改变1的个数。
但是,出现数字2的时候,第二个1向前挪了一位,这实际上是把LIS为2的序列由13变成了12,这里对后续的影响是不同的,可以手推323来解答你的困惑。

于是到此我们就知道了sta的真正含义。
如果sta的第a位上为1,并且之前(包括自己)有b个1,那么长度为b的上升序列的末尾的最小值就是a

这里还要判断前面是不是有前导0,不然01会被当成LIS是2,但是其实是1.
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define ls (t<<1)
#define rs ((t<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100086;
const int inf = 2.1e9;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);

ll a,b;
int k;
int bit[20];

int dp[20][1100][12];

int cal(int t){
    int ans=0;
    while (t){
        ans+=(t&1);
        t>>=1;
    }
    return ans;
}
int new_sta(int sta,int k){
    for(int i=k;i<10;i++){
        if(sta&(1<<i)){
            return (sta^(1<<i))|(1<<k);
        }
    }
    return sta|(1<<k);
}

ll dfs(int pos,int sta,bool limit,bool pre){
    if(pos==-1){
        return cal(sta)==k;
    }
    if(!limit&&dp[pos][sta][k]!=-1){ return dp[pos][sta][k];}
    ll ans=0;
    int up=limit?bit[pos]:9;
    for(int i=0;i<=up;i++){
        ans+=dfs(pos-1,(pre&&i==0)?0:new_sta(sta,i),limit&&(i==up),pre&&(i==0));
    }
    if(!limit){dp[pos][sta][k]=ans;}
    return ans;
}
ll solve(ll t){
    int pos=0;
    while(t){
        bit[pos++]=t%10;
        t/=10;
    }
    return  dfs(pos-1,0,true,true);
}

int main()
{
//    ios::sync_with_stdio(false);
//    freopen("in.txt","r",stdin);

    memset(dp,-1,sizeof(dp));
    int T;
    scanf("%d",&T);
    int cases=0;
    while (T--){
        cases++;
        scanf("%lld%lld%d",&a,&b,&k);
        printf("Case #%d: %lld
",cases,solve(b)-solve(a-1));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ZGQblogs/p/10679934.html