hdu 5248 贪心

题意:

链接:点我

二分代价,由于序列是单增的,我们使前面一个数相对取最小,这样后面的数变化的值也能相对较小wa了好多次,发现上限少取了个0

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****
");
15 const int MAXN=100005;
16 int n,m,tt;
17 int a[MAXN],b[MAXN];
18 bool check(int mid)
19 {
20     for(int i=1;i<=n;i++)
21     {
22         b[i]=a[i];
23     }
24     for(int i=1;i<=n;i++)
25     {
26         if(i==1)
27         {
28             b[i]-=mid;
29             continue;
30         }
31         if(b[i]<=b[i-1])
32         {
33             if((b[i-1]+1)-b[i]<=mid)
34                 b[i]=b[i-1]+1;
35             else
36             {
37                 return 0;
38             }
39 
40         }
41         if(b[i]-mid>b[i-1])
42         {
43             b[i]=b[i]-mid;
44         }
45         else
46         {
47             b[i]=b[i-1]+1;
48         }
49     }
50     return 1;
51 
52 }
53 int main()
54 {
55     int i,j,k;
56     #ifndef ONLINE_JUDGE
57     freopen("1.in","r",stdin);
58     #endif
59     int ca=1;
60     scanf("%d",&tt);
61     while(tt--)
62     {
63         printf("Case #%d:
",ca++);
64         scanf("%d",&n);
65         for(i=1;i<=n;i++)   scanf("%d",a+i);
66         int l=0;
67         int r=1000005;
68         int ans=0;
69         while(l<=r)
70         {
71             int mid=(l+r)>>1;
72             if(check(mid))
73             {
74                 ans=mid;
75                 r=mid-1;
76             }
77             else
78                 l=mid+1;
79         }
80         printf("%d
",ans);
81     }
82 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4541236.html