首页 > 代码库 > 【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
nlogn求出最长上升子序列长度。
对每次询问,贪心地回答。设输入为x。当前数a[i]可能成为答案序列中的第k个,则若 f[i]>=x-k && a[i]>ans[k-1] 即可。
f[i]表示以a[i]开头的最长上升子序列长度。
但这个东西难以统计。so 我们将原序列反序,求f[i] 表示以 a[i]为结尾的最长下降子序列长度即可。最后再将f、a reverse一下。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int a[10001],n,m,en=1,len,last; 5 int b[10001];//b[i]:将a翻转后,长度为i的最长下降子序列的末尾 6 int c[10001];//c[i]:将a翻转后,以a[i]开头的最长下降子序列的长度 7 bool cmp(const int &a,const int &b){return a>b;} 8 int main() 9 {10 scanf("%d",&n);11 for(int i=1;i<=n;i++) scanf("%d",&a[n-i+1]);12 scanf("%d",&m);13 b[1]=a[1]; c[1]=1;14 for(int i=2;i<=n;i++)15 {16 int *p=lower_bound(b+1,b+en+1,a[i],cmp);17 if(!(*p)) ++en;18 *p=a[i];19 c[i]=p-b;20 }21 for(int i=1;i<=(n>>1);i++) swap(c[i],c[n-i+1]),swap(a[i],a[n-i+1]);22 for(int i=1;i<=m;i++)23 {24 scanf("%d",&len);25 if(len>en)26 {27 puts("Impossible");28 continue;29 } last=0;30 for(int j=1;j<=n;++j)31 if(c[j]>=len&&a[j]>last)32 {33 printf("%d",last=a[j]);34 if(!(--len))35 {36 puts("");37 break;38 } putchar(‘ ‘);39 }40 }41 return 0;42 }
【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。