zoukankan      html  css  js  c++  java
  • hdu 5125 magic balls

    题意:求a数组的LIS,但是加了一个条件,为了LIS最大 b[i] a[i]可以交换。最多交换m次;

    思路:我们令dp[i][j][l]表示i在最长上升子序列中,已经损失j点能量,第i个人转换了ai和bi的最长上升子序列的数目,可以得到方程 dp[i][j][0]=max{dp[k][j][0](a[k]<a[i])+1,dp[k][j][1](b[k]<a[i])+1},dp[i][j][1]=max(dp[k][j-1][0](a[k]<b[i])+1,dp[k][j-1][1](b[k]<b[i])+1)。这样是n^2k的,我们换个思路,即从k能转移到哪些i,我们先将体积离散化,再用m颗线段树来维护已损失j点能量的情况下体积为某数的最长上升子序列。这样可以做到nlgnk,不过线段树常数写的很大的话还是会TLE,考虑到求最大值实际上是求1~x的最大值,这样我们可以通过常数非常小的树状数组来解决。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 20000
     5 using namespace std;
     6 
     7 int n,m;
     8 int a[1001],b[1001];
     9 int dp[1001][1001][2];
    10 int c[1001][2000];
    11 int f[2001],cnt;
    12 
    13 inline int Find(int xx)
    14 {
    15     return lower_bound(f,f+cnt,xx)-f+1;
    16 }
    17 
    18 inline void insert(int *c,int x,int cc)
    19 {
    20     for(; x<=cnt; x+=x&-x)
    21     {
    22         c[x]=max(c[x],cc);
    23     }
    24 }
    25 
    26 inline int get_max(int *c,int x)
    27 {
    28     int ans=0;
    29     for( ; x; x-=x&-x)
    30     {
    31         ans=max(ans,c[x]);
    32     }
    33     return ans;
    34 }
    35 
    36 int main()
    37 {
    38     int T;
    39     scanf("%d",&T);
    40     while(T--)
    41     {
    42     
    43         int n,m;
    44         scanf("%d%d",&n,&m);
    45         cnt=0;
    46         for(int i=1;i<=n;++i)
    47         {
    48             scanf("%d%d",a+i,b+i);
    49             f[cnt++]=a[i];
    50             f[cnt++]=b[i];
    51         }
    52         sort(f,f+cnt);
    53         cnt=unique(f,f+cnt)-f;
    54         for(int i=1;i<=n;++i) 
    55         {
    56             a[i]=Find(a[i]);
    57             b[i]=Find(b[i]);
    58         }
    59         memset(c,0,sizeof(c));
    60         int ans=0;
    61         for(int i=1;i<=n;++i)
    62         {
    63             for(int j=0;j<=min(m,i);++j)
    64             {
    65                 dp[i][j][0]=get_max(c[j],a[i]-1)+1;
    66                 ans=max(ans,dp[i][j][0]);
    67                 if(j)
    68                 {
    69                     dp[i][j][1]=get_max(c[j-1],b[i]-1)+1;
    70                     ans=max(ans,dp[i][j][1]);
    71                 }
    72             }
    73             for(int j=0;j<=min(m,i);++j)
    74             {
    75                 insert(c[j],a[i],dp[i][j][0]);
    76                 if(j) insert(c[j],b[i],dp[i][j][1]);
    77             }
    78         }
    79         printf("%d
    ",ans);
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    K210识别水果模型
    一键开关机短路
    Arudino IDE添加STM32官方管理器stm32duino / Arduino_Core_STM32
    ESP32 Ble
    Blynk软件配置及Mixly编程教程
    Laravel安装及配置,完成基础的demo
    electron下载/打包慢?解决办法.....
    ESP32+PHP+MYSQL 搭建自己的物联网平台Demo
    PCA9536读写测试之MicroPython
    MSF实验2
  • 原文地址:https://www.cnblogs.com/fanminghui/p/4140102.html
Copyright © 2011-2022 走看看