zoukankan      html  css  js  c++  java
  • $HDOJ5542 The Battle of Chibi$ 数据结构优化$DP$

    $AcWing$

    $Description$

    $Sol$

    首先显然是是以严格递增子序列的长度为阶段,由于要单调递增,所以还要记录最后一位的数值
    $F[i][j]$表示前$i$个数中以$A_i$结尾的长度为j单调递增序列有多少个
    $F[i][j]=sum_{k<i且A_k<A_i}^{ }F[k][j-1]$
    注意到,如果没有$A_k<A_i$这个条件我们就可以直接维护前缀和了
    有$A_k<A_i$这个条件,可以考虑维护$A_i$为下标,$F[i][j-1]$为值的数组的前缀和
    $A_i$的值会过大而不能作为下标,要离散化
    但是$i$每增加$1$,这个数组并不像之前那样简单的在数组后面加一个值,而是在不确定的地方修改,这样的话如果再是朴素地维护前缀和也起不到上面优化的作用了
    待修改的区间求和问题$???$树状数组$!!!$
    也就是说维护一个以$A_i$的离散值为下标,$F[i][j-1]$为值的树状数组就好啦
    然后讲下细节(敖丙说了细节决定成败$qwq$).就是初始化是$f[0][0]=1$,但是众所周知树状数组的下标不可以为$0$,所以把整个树状数组往右移一位.
     

    $Code$

     1 #include<bits/stdc++.h>
     2 #define il inline
     3 #define Rg register
     4 #define go(i,a,b) for(Rg int i=a;i<=b;i++)
     5 #define yes(i,a,b) for(Rg int i=a;i>=b;i--)
     6 #define mem(a,b) memset(a,b,sizeof(a));
     7 #define int long long
     8 using namespace std;
     9 il int read()
    10 {
    11     int x=0,y=1;char c=getchar();
    12     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    13     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    14     return x*y;
    15 }
    16 const int N=1010,mod=(1e9)+7;
    17 int T,n,n1,m,as,a[N],b[N],v[N],c[N],f[N][N];
    18 il int Find(int x){return find(b+1,b+n1+1,x)-b;}//find(b+1,b+n1+1,x)-b;}
    19 il int lowbit(int x){return x&(-x);}
    20 il void add(int p,int w){while(p<=n1){c[p]=(c[p]+w)%mod;p+=lowbit(p);}}
    21 il int sum(int p){int ret=0;while(p){ret=(ret+c[p])%mod;p-=lowbit(p);}return ret%mod;}
    22 main()
    23 {
    24     T=read();
    25     go(TT,1,T)//remember to init
    26     {
    27         n=read(),m=read();
    28         go(i,1,n)a[i]=b[i]=read();
    29         sort(b+1,b+n+1);
    30         n1=unique(b+1,b+n+1)-(b+1);
    31         go(i,1,n){v[i]=Find(a[i]);}
    32         f[0][0]=1;
    33         go(i,1,m)
    34         {
    35             mem(c,0);if(i==1)add(1,1);
    36             go(j,1,n)f[i][j]=sum(v[j]),add(v[j]+1,f[i-1][j]);
    37         }
    38         as=0;go(i,1,n)as=(as+f[m][i])%mod;
    39         printf("Case #%lld: %lld
    ",TT,as);
    40     }
    41     return 0;
    42 }
    View Code
    光伴随的阴影
  • 相关阅读:
    js中点击空白区域时文本框与隐藏层的问题
    嗨翻C语言
    人工模拟获取latch
    如何JOPtionPane的showConfirmDialog对话框button设置监视器
    本机Ajax异步通信
    Project Euler:Problem 28 Number spiral diagonals
    Maven软件项目管理工具
    第一个打击木马病毒查杀007一片:反向熊猫的分析(下一个)
    Redefine:Change in the Changing World
    不一致的文件编码读取和写入文件乱码解决方案
  • 原文地址:https://www.cnblogs.com/forward777/p/11262650.html
Copyright © 2011-2022 走看看