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 }
  • 相关阅读:
    Linux下动态库生成和使用
    ELK日志平台
    zabbix 监控端口
    zabbix 分布式zabbix_proxy
    zabbix 邮件报警 监控mysql主从
    Kubernetes 本地仓库
    kubernetes ui 搭建
    Kubernetes K8s
    Dockerfile
    Docker 指定容量
  • 原文地址:https://www.cnblogs.com/silver-bullet/p/3259205.html
Copyright © 2011-2022 走看看