1275: God's ladder [DP]
时间限制: 1 Sec 内存限制: 128 MB Special Judge题目描述
天明来到神之宫殿,在他眼前出现了若干个石柱,每个石柱上有1枚金币,天明可以任意选择一个石柱开始,然后向前方的石柱瞬移,而且他所瞬移到的石柱的高度必须要大于现在所在石柱的高度。
求天明所能获得的最大金币数以及任意一种可以获得这么多金币的路线(每个石柱的高度)。
输入
第一行一个数n,表示石柱的个数。
然后2~n+1行,每行一个石柱的高度h[i],分别是1,2,,n石柱的高度。
2<n<200100;1<= h[i] < 15000000;
输出
第一行为一个数m,表示最大金币数。
2~m+1行,每行一个数,分别是每次所瞬移到的石柱的高度。
样例输入
7
3
1
2
5
9
6
7
样例输出
5
1
2
5
6
7
思路:O(nlgn)否则超时,二分+dp;
举个例子:1 6 7 3 4 8 5
下标: 1 2 3 2 3 4 4
逆着输出:5 4 3 1(这份序列)
下标则是:4 3 2 1
#include<cstdio>
#define SIZE 200110
using namespace std;
int stack[SIZE];
int a[SIZE],f[SIZE],lis[SIZE];
int main()
{
int i,j,n,top,temp;
scanf("%d",&n);
top=0;
stack[0]=-1;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
temp=a[i];
if (temp>stack[top])
{
stack[++top]=temp;
f[i]=top;
}
else
{
int low=1,high=top,mid;
while(low<=high)
{
mid=(low+high)/2;
if (temp>stack[mid])
low=mid+1;
else
high=mid-1;
}
stack[low]=temp;
f[i]=low;
}
}
printf("%d\n",top);
int t=top;
for(i=n;i>=0;i--)
{
if(f[i]==t)
lis[--t]=a[i];
if(t<0)
break;
}
for(i=0;i<top;i++)
printf("%d\n",lis[i]);
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define SIZE 200110
int stack[SIZE];
int a[SIZE],f[SIZE],lis[SIZE];
int main()
{
int i,j,n,temp;
scanf("%d",&n);
int top=0;
stack[0]=-1;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
temp=a[i];
if (temp>stack[top])
{
stack[++top]=temp;
f[i]=top;
}
else
{
int low=lower_bound(stack,stack+top,temp)-stack;//感觉比二分耗时
stack[low]=temp;
f[i]=low;
}
}
printf("%d\n",top);
int t=top;
for(i=n;i>=0;i--)
{
if(f[i]==t)
lis[--t]=a[i];
if(t<0)
break;
}
for(i=0;i<top;i++)
printf("%d\n",lis[i]);
return 0;
}