zoukankan      html  css  js  c++  java
  • HDOJ 5542 The Battle of Chibi

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5542

    题目大意:在n个数中找长度为m的单调上升子序列有多少种方案

    题目思路:DP,离散化,树状数组优化,

    dp[i][j]代表大小为i的数 长度为j时的方案,状态转移方程dp[i][j]=simiga(dp[1..i-1][j-1]) 如果直接求和的话,复杂度是n^3不行

    用树状数组优化求和 复杂度n^2logn 

    n<=1000,a[i]<=1e9,所以离散化搞一下就行

    //更新一下 这题在HDU上面能过 但是在电科上面会T

    //因为有个地方可以优化不少 在我们枚举当前大小为i长度为j的时候 也就是query(a[i]-1,j-1)时,如果该表达式为0,那么j-1之后的长度肯定时达不到的

    直接break就行了

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=1100;
     7 const long long  mod=1e9+7;
     8 long long  tree[maxn][maxn];
     9 int dp[maxn][maxn];
    10 int a[maxn],b[maxn];
    11 void add(int i,int m,int k){
    12     for(i;i<=maxn;i+=(i&(-i))) (tree[m][i]+=k)%=mod;
    13 }
    14 long long  query(int i,int m){
    15     long long sum=0;
    16     for(i;i>0;i-=(i&(-i))) (sum+=tree[m][i])%=mod;
    17     return sum%mod;
    18 }
    19 void init(int n,int m){
    20     for(int i=0;i<=m+1;i++){
    21         for(int j=0;j<=n+1;j++){
    22             dp[i][j]=0;
    23         }
    24     }
    25     for(int i=0;i<=m+1;i++)
    26     memset(tree[i],0,sizeof(tree[i]));
    27 }
    28 void solve(int T){
    29     printf("Case #%d: ",T);
    30     int n,m;
    31     scanf("%d %d",&n,&m);
    32     init(n,m);
    33     for(int i=1;i<=n;i++) scanf("%d",&b[i]),a[i]=b[i];
    34     sort(b+1,b+1+n);
    35     int size=unique(b+1,b+1+n)-b;
    36     for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+size,a[i])-b;
    37     for(int i=1;i<=n;i++){
    38         for(int j=1;j<=min(i+1,m);j++){
    39             if(j==1) dp[j][a[i]]=1;
    40             else 
    41             dp[j][a[i]]=query(a[i]-1,j-1)%mod;
    42             if(dp[j][a[i]]==0) break;//如果长度j都到不了 那么j以后的肯定也是到不了
    43             add(a[i],j,dp[j][a[i]]);
    44         }
    45     }
    46     printf("%lld
    ",query(size,m)%mod);
    47 }
    48 int main(){
    49     int T;
    50     scanf("%d",&T);
    51     for(int i=1;i<=T;i++) solve(i);
    52 }
  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/as3asddd/p/6071995.html
Copyright © 2011-2022 走看看