【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5773
题目大意:
T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何自然数)
题目思路:
【动态规划】【二分】【最长上升子序列】
按最长上升子序列做,遇到0的时候更新所有长度的最优解。(这种暴力解法都能过?而且还比标解快?)
1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 //#include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define eps (1e-8) 22 #define J 10000000 23 #define MAX 0x7f7f7f7f 24 #define PI 3.1415926535897 25 #define N 100004 26 using namespace std; 27 typedef long long LL; 28 int cas,cass; 29 int n,m,lll,ans; 30 int a[N],q[N]; 31 void work() 32 { 33 int i,j,l,r,mid; 34 lll=0; 35 memset(q,-1,sizeof(q)); 36 for(i=1;i<=n;i++) 37 { 38 if(a[i]==0) 39 { 40 q[lll+1]=q[lll]+1; 41 for(j=lll;j>1;j--)q[j]=min(q[j-1]+1,q[j]); 42 q[1]=0;lll++; 43 continue; 44 } 45 l=0,r=lll; 46 while(l<r) 47 { 48 mid=(l+r+1)>>1; 49 if(a[i]>q[mid])l=mid; 50 else r=mid-1; 51 } 52 q[r+1]=a[i]; 53 lll=max(lll,r+1); 54 } 55 } 56 int main() 57 { 58 #ifndef ONLINE_JUDGE 59 freopen("1.txt","r",stdin); 60 // freopen("2.txt","w",stdout); 61 #endif 62 int i,j; 63 // for(scanf("%d",&cas);cas;cas--) 64 for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 65 // while(~scanf("%s",s)) 66 // while(~scanf("%d",&n)) 67 { 68 printf("Case #%d: ",cass); 69 scanf("%d",&n); 70 for(i=1;i<=n;i++) 71 { 72 scanf("%d",&a[i]); 73 } 74 work(); 75 printf("%d\n",lll); 76 } 77 return 0; 78 } 79 /* 80 // 81 82 // 83 */
正解是把0先都拿出来,非0的数都减去它前面0的个数(0可以变成任何自然数),求最长上升子序列,再把0的数加上即为答案。
1 // 2 //by coolxxx 3 ////<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 //#include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define mem(a,b) memset(a,b,sizeof(a)) 22 #define eps (1e-8) 23 #define J 10000000 24 #define MAX 0x7f7f7f7f 25 #define PI 3.14159265358979323 26 #define N 100004 27 using namespace std; 28 typedef long long LL; 29 int cas,cass; 30 int n,m,lll,ans; 31 int a[N],q[N]; 32 void work() 33 { 34 int i,j,l,r,mid; 35 lll=0; 36 memset(q,-1,sizeof(q)); 37 for(i=1;i<=n;i++) 38 { 39 l=0,r=lll; 40 while(l<r) 41 { 42 mid=(l+r+1)>>1; 43 if(a[i]>q[mid])l=mid; 44 else r=mid-1; 45 } 46 q[r+1]=a[i]; 47 lll=max(lll,r+1); 48 } 49 } 50 int main() 51 { 52 #ifndef ONLINE_JUDGE 53 freopen("1.txt","r",stdin); 54 // freopen("2.txt","w",stdout); 55 #endif 56 int i,j; 57 // for(scanf("%d",&cas);cas;cas--) 58 for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 59 // while(~scanf("%s",s)) 60 // while(~scanf("%d",&n)) 61 { 62 printf("Case #%d: ",cass); 63 scanf("%d",&n); 64 m=0; 65 for(i=1;i<=n;i++) 66 { 67 scanf("%d",&a[i]); 68 if(a[i]==0)n--,i--,m++; 69 else a[i]-=m; 70 } 71 work(); 72 printf("%d\n",lll+m); 73 } 74 return 0; 75 } 76 /* 77 // 78 79 // 80 */