POJ 2533 最长不降子序列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 const int Maxn=1010; 3 int a[Maxn],Pos[Maxn],F[Maxn],n,Ans; 4 inline int Max(int x,int y) {return x>y?x:y;} 5 inline int Find(int x) 6 { 7 int l=1,r=Ans,Res; 8 while (l<=r) 9 { 10 int mid=(l+r)>>1; 11 if (a[Pos[mid]]<x) Res=mid,l=mid+1; else r=mid-1; 12 } 13 return Res; 14 } 15 int main() 16 { 17 scanf("%d",&n); 18 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 19 F[1]=1; Pos[1]=1; Ans=1; 20 for (int i=2;i<=n;i++) 21 { 22 int t=Find(a[i]); 23 Pos[t+1]=i; 24 F[i]=t+1; 25 Ans=Max(Ans,F[i]); 26 } 27 printf("%d\n",Ans); 28 return 0; 29 }
BZOJ 3886
状压DP+贪心
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 const int Maxn=22; 4 const int Maxm=1010; 5 const int Inf=0x3f3f3f3f; 6 inline int Min(int x,int y) {return x>y?y:x;} 7 inline int Max(int x,int y) {return x>y?x:y;} 8 int n,m,f[1<<Maxn],Ans=Inf; 9 int Len[Maxn],P[Maxn],C[Maxn][Maxm]; 10 int find(int x,int id) 11 { 12 int l=0,r=P[id]; 13 while (l<r) 14 { 15 int mid=(l+r+1)>>1; 16 if (C[id][mid]<=x) l=mid; 17 else r=mid-1; 18 } 19 return l; 20 } 21 int main() 22 { 23 // freopen("c.in","r",stdin); 24 scanf("%d%d",&n,&m); 25 for (int i=1;i<=n;i++) 26 { 27 scanf("%d%d",&Len[i],&P[i]); 28 for (int j=1;j<=P[i];j++) scanf("%d",&C[i][j]); 29 } 30 memset(f,-1,sizeof(f)),f[0]=0; 31 for (int i=0;i<(1<<n);i++) 32 { 33 if (f[i]==-1) continue; 34 if (f[i]>=m) 35 { 36 int j,k; 37 for (j=0,k=i;k;k-=(k&(-k))) j++; 38 Ans=Min(Ans,j); 39 continue; 40 } 41 for (int j=1;j<=n;j++) 42 { 43 if (i&(1<<(j-1))) continue; 44 int k=find(f[i],j); 45 if (k==0) continue; 46 f[i|(1<<(j-1))]=Max(f[i|(1<<(j-1))],C[j][k]+Len[j]); 47 } 48 } 49 printf("%d\n",Ans==Inf?-1:Ans); 50 return 0; 51 }