1 条题解
-
0
题目大意
有 颗行星,求从 出发到 所需最少加注次数,无解输出 。
思路
考虑贪心,发现每次选可以走到最远的 加注最优。 :::info[证明] 因为可以在中途停下,所以每次选走到最远的包含了所有情况。假设在一次飞行中,没选最优情况,而选了 ,其中 ,则本来当前最大到达区间 ,而现在只有 ,若下次加注的位置在 ,那么在 加注没法保证最优。 ::: 预处理 表示 之后第一个与 同类型的位置。
初始区间 , 已加注。
每次在 中找 的最大值,设 表示 最大的 。
若最大值 则无解。
否则加注 ,更新 ,继续。
当 时结束。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll n,a[300005],u[300005],v[300005],l=1,r,k=1,s=1,d; vector<ll> t; int main(){ scanf("%lld",&n); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); v[u[a[i]]]=i; u[a[i]]=i;//u表示上一个a[i]的下标 } r=v[1];//初始区间右端点 t.push_back(1);//记录加注路径 while(1){ if(r==n){//达到n printf("%lld\n",s); for(int i=0;i<t.size();i++)printf("%lld ",t[i]); break; } d=0;//记录a[i]最大值 while(l<r){ l++;//l不会退,一路扫到r if(v[l]>d){ d=v[l]; k=l;//k记录最大i } } if(d<=r){//无解 printf("0"); break; } t.push_back(k);//最优选择k放入加注路径 s++; r=d; } return 0; }
- 1
信息
- ID
- 10347
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者