USACO 2017 December Contest Platinum T3: Greedy Gift Takers

Subject to the effect

There are N ( 1 N 1E . 5) arranged in a sequence cows, numbered from 1 to N, the number of cattle HOL 1, N number of cattle in the tail.

Each cow is located HOL i get a gift, and then inserted into the mantissa team C i position before the cow. . For chestnut: initial queue 1,2,3,4,5  C . 1 = 2, C 2  =. 3, the first operation sequence is 2,3,1,4,5, second operation after the sequence 3,2,1,4,5. Repeat unlimited operation, seeking the last few head of cattle can not get a gift.

Topic analysis

One up there it is plausible that if a person can not get the original sequence present in person behind him certainly not a gift, because the people behind the jump is less than the front.

So long as we find the first person to get the gift, the math is the answer.

In other words, we need to find the last person to get a gift.

Obviously, this monotone can be two.

Half the number of people you can get a gift, then how can judge it feasible?

We should judge before mid  whether to form a loop. If the formation of a cycle, the mid not get a gift.

How to determine the cycle of it, appear in the first position of the i-th head of cattle more than i, this i would have been stuck in this cow before the i-th position.

Note that when the Check should c [1] ~ c [mid-1] sort, because c take large gifts may also jump to the front after the first mid, and small c will never be left behind, and this is equivalent to "c larger cow" c 1 on the Save.

And let c small jump back to the whole cycle does not constitute, what we really want to judge.

 (I do not understand can look at the code carefully think about it)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e5+10;
 4 
 5 int n,ans;
 6 int c[MAXN],num[MAXN];
 7 inline bool Check(int mid){
 8     if(mid==1) return true;
 9     for(int i=1;i<mid;++i) num[i]=c[i];
10     sort(num+1,num+mid);
11     int lim=n-mid;
12     for(int i=1;i<mid;++i){
13         if(num[i]>lim) return false;
14         ++lim;
15     }
16     return true;
17 }
18 int main(){
19     scanf("%d",&n);
20     for(int i=1;i<=n;++i)
21         scanf("%d",&c[i]);
22     int l=1,r=n+1;
23     while(l<=r){
24         int mid=(l+r)>>1;
25         if(Check(mid)){
26             ans=mid;l=mid+1;
27         }
28         else
29             r=mid-1;
30     }
31     printf("%d\n",n-ans);
32     return 0;
33 }

 

Guess you like

Origin www.cnblogs.com/LI-dox/p/11235645.html