zoukankan      html  css  js  c++  java
  • hdu 4352 XHXJ's LIS

    题意:

      先定义一个数的power value,把这个数看成一个字符串,他的最长上升子序列的长度就是他的power value,求某个区间内power value等于k的数的个数。

    解法:

      很显然要数位DP,先考虑LIS的nlogn解法,我们用dp[len]记录LIS长度为len时的最后一个数的大小,然后不断更新这些值,让每一个值都尽可能小,比如我现在的LIS是1 2 4 6,这时候下一个数是3,那么我们就要更新成1 2 3 6,让前面的数尽可能的小,这样就是为了能让后面的数有更多的机会被加入。

      同理,因为数字只有10个,我们可以状态压缩,记录每个数字是否出现在当前的LIS中,然后根据这个状态,用前面的办法转移就行了。

      

      dp[len][number][mask]记录第len位数字是number当前LIS的状态是mask的答案。状态转移可以预处理出来

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<bitset>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<iostream>
     7 #include<string>
     8 #include<vector>
     9 #include<queue>
    10 #include<deque>
    11 #include<set>
    12 #include<map>
    13 #include<algorithm>
    14 using namespace std;
    15 typedef long long ll;
    16 const int N = 20;
    17 ll dp[N][10][1<<10][11];
    18 int hash[1<<10];
    19 int next[1<<10][10];
    20 int bit[N],K;
    21 int go(int mask,int number){
    22     int pos = -1;
    23     for(int i = number;i <=9;i++)
    24         if(mask & (1<<i)){
    25             pos = i;
    26             break;
    27         }
    28     if(pos == -1)mask |= 1<<number;
    29     else{
    30         mask ^= 1<<pos;
    31         mask |= 1<<number;
    32     }
    33     return mask;
    34 }
    35 void init(){
    36     memset(dp,-1,sizeof(dp));
    37     for(int i=0;i<1<<10;i++){
    38         hash[i] = 0;
    39         for(int j=0;j<10;j++)
    40             if(i&(1<<j))hash[i]++;
    41     }
    42     for(int i = 0;i < 1<<10;i++)
    43         for(int j = 0;j < 10;j++)
    44             next[i][j] = go(i,j);
    45     for(int i = 0;i < 15;i++){
    46 //        cout<<"cur ";
    47 //        cout<<(bitset<10>)i<<endl;
    48         for(int j=0;j<10;j++){
    49 //            cout<<"j = "<<j<<" "<<(bitset<10>)next[i][j]<<endl;
    50         }
    51     }
    52 }
    53 ll dfs(int pos,int number,int mask,bool isZero,bool flag){
    54     if(pos == 0)return hash[mask] == K;
    55     if(flag && ~dp[pos][number][mask][K])return dp[pos][number][mask][K];
    56     ll ans = 0;
    57     int u = flag ? 9:bit[pos];
    58     for(int d = 0;d <= u;d++){
    59         if(isZero && d == 0)ans += dfs(pos-1,d,0,1,flag || d < u);
    60         else{
    61             ans += dfs(pos-1,d,next[mask][d],0,flag || d < u);
    62         }
    63     }
    64     if(flag)dp[pos][number][mask][K] = ans ;
    65     return ans;
    66 }
    67 ll solve(ll n){
    68     int len = 0;
    69     while(n){
    70         bit[++len] = n % 10;
    71         n /= 10;
    72     }
    73     return dfs(len,0,0,1,0);
    74 }
    75 int main(){
    76     init();
    77     ll L,R;
    78     int T;cin >> T;
    79     for(int cas = 1;cas <= T;cas++){
    80         cin >> L >> R >> K;
    81         cout<<"Case #"<<cas<<": "<<solve(R) - solve(L - 1)<<endl;
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    实验三-并发程序 20175201张驰
    20175201 20175215 20175229 实验二 固件程序设计
    20175201 20175215 20175229 实验一 开发环境的熟悉
    #20175201 实验五 网络编程与安全
    云班课选做
    2019-2020-12 20175313 20175328 20175329 实验五 通讯协议设计
    2019-2020-1 20175313 20175328 20175329 实验四 外设驱动程序设计
    2019-2020-1 20175313 20175328 20175329 实验三 并发程序
    20175329&20175313&20175318 2019-2020 《信息安全系统设计基础》实验三
    20175329&20175313&20175318 2019-2020 《信息安全系统设计基础》实验二
  • 原文地址:https://www.cnblogs.com/silver-bullet/p/3259205.html
Copyright © 2011-2022 走看看