POJ 2533 最长不降子序列

 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 }
POJ 2533

BZOJ 3886

 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 }
BZOJ 3886