传送门
B.Game(贪心+思维)
•题意
一步可以走一个或者两个,求依次进入n个区间[li,ri]的最少步数
•思路
就当前位置cur来说,
1)如果下一个任务的区间包括当前位置,那就可以不动
2)如果下一个任务区间在当前位置左边,那就向下一个的左边界移动
①如果正好可以全走两个格子的话,就在此位置
如果不可以全走两个格子的话,
②如果再下一个位置在左边的话,那就不动
③如果再下一个位置在右边的话,那就把走的一格变成两格,在左边界往右一个位置
3)如果下一个任务区间在当前位置右边,那就向下一个的右边界移动
①如果正好可以全走两个格子的话,就在此位置
如果不可以全走两个格子的话,
②如果再下一个位置在右边的话,那就不动
③如果再下一个位置在左边的话,那就把走的一格变成两格,在右边界往左一个位置
起点在最小区间的左边界或者右边界
•代码
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1000+50; 5 6 int n; 7 int l[maxn]; 8 int r[maxn]; 9 10 ll F(int k,int p) 11 { 12 ll ans=0; 13 while(k <= n) 14 { 15 if(p >= l[k] && p <= r[k]) 16 { 17 k++; 18 continue; 19 } 20 if(l[k] > p) 21 { 22 ll cur=l[k]-p; 23 ans += (cur+1)/2; 24 p=l[k]; 25 26 if(cur%2 == 0) 27 continue; 28 29 int tmp=k; 30 for(;tmp <= n && l[tmp] <= p && r[tmp] > p;tmp++); 31 32 if(tmp > n) 33 return ans; 34 35 if(l[k] != r[k] && l[tmp] > p) 36 p++; 37 } 38 else 39 { 40 ll cur=p-r[k]; 41 ans += (cur+1)/2; 42 p=r[k]; 43 44 if(cur%2 == 0) 45 continue; 46 47 int tmp=k; 48 for(;tmp <= n && l[tmp] < p && r[tmp] >= p;tmp++); 49 50 if(tmp > n) 51 return ans; 52 53 if(l[k] != r[k] && r[tmp] < p) 54 p--; 55 } 56 } 57 return ans; 58 } 59 int main() 60 { 61 int T; 62 scanf("%d",&T); 63 while(T--) 64 { 65 scanf("%d",&n); 66 for(int i=1;i <= n;++i) 67 scanf("%d%d",l+i,r+i); 68 69 int L=l[1]; 70 int R=r[1]; 71 for(int i=2;i <= n;++i) 72 { 73 int x=max(max(l[i],l[i-1]),L); 74 int y=min(min(r[i],r[i-1]),R); 75 76 if(x > y) 77 break; 78 L=x; 79 R=y; 80 } 81 ll ans=min(F(1,L),F(1,R)); 82 83 printf("%I64d ",ans); 84 } 85 return 0; 86 }