• 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 }
  • 相关阅读:
    不用循如何计算数组累加和
    mysql通过binlog恢复删除数据
    windows下打开binlog
    mysql的binlog
    枚举实现线程池单例
    AtomicInteger的CAS算法浅析
    不用循环如何计算1累加到100
    MongoDB查询报错:class com.mongodb.MongoSecurityException: Exception authenticating MongoCredential
    Senparc.Weixin微信开发(3) 自定义菜单与获取用户组
    Senparc.Weixin微信开发(2) 消息机制和上下文(Session)
  • 原文地址:https://www.cnblogs.com/as3asddd/p/6071995.html
Copyright © 2020-2023  润新知