【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3594
【题意】
给定一个n个数的序列,有K次将一个区间内的数加1的机会,问最长不下降子序列。
【思路】
首先知道每次加1一个区间为[i,n]肯定不会差。
设f[i][j]为前i个数,还有j次机会的LIS,则有转移式:
f[i][j] = max{ f[a][b],h[a]+b<=h[i]+j }
则可以用二维BIT加速方程转移。
【代码】
1 #include<set> 2 #include<cmath> 3 #include<queue> 4 #include<vector> 5 #include<cstdio> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt) 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 11 using namespace std; 12 13 typedef long long ll; 14 const int M = 5600+10; 15 const int N = 500+10; 16 17 ll read() { 18 char c=getchar(); 19 ll f=1,x=0; 20 while(!isdigit(c)) { 21 if(c==‘-‘) f=-1; c=getchar(); 22 } 23 while(isdigit(c)) 24 x=x*10+c-‘0‘,c=getchar(); 25 return x*f; 26 } 27 28 int C[N][M],n,K,a[10001]; 29 30 int lowbit(int x) 31 { 32 return x&-x; 33 } 34 void upd(int x,int y,int v) 35 { 36 for(int i=x;i<N;i+=lowbit(i)) 37 for(int j=y;j<M;j+=lowbit(j)) 38 C[i][j]=max(C[i][j],v); 39 } 40 int query(int x,int y) 41 { 42 int ans=0; 43 for(int i=x;i;i-=lowbit(i)) 44 for(int j=y;j;j-=lowbit(j)) 45 ans=max(ans,C[i][j]); 46 return ans; 47 } 48 49 int main() 50 { 51 n=read(),K=read(); 52 FOR(i,1,n) a[i]=read(); 53 K++; 54 int ans=1; 55 FOR(i,1,n) for(int j=K;j;j--) 56 { 57 int x=query(j,a[i]+j)+1; 58 ans=max(ans,x); 59 upd(j,a[i]+j,x); 60 } 61 printf("%d\n",ans); 62 return 0; 63 }
时间: 2024-12-25 03:43:03