cf D. Levko and Array
7424 ワード
http://codeforces.com/contest/361/problem/D
隣接する2つの数の差の絶対値を二分で探索し,その後dpで数の変化回数を記録した.dp[i]は、iより前に変化した回数を表し、|a[i]−a[j]|<=(i−j)*midが変化する必要がある場合を表す.
View Code
隣接する2つの数の差の絶対値を二分で探索し,その後dpで数の変化回数を記録した.dp[i]は、iより前に変化した回数を表し、|a[i]−a[j]|<=(i−j)*midが変化する必要がある場合を表す.
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4 #define LL __int64
5 using namespace std;
6 const LL inf=2000000000;
7 int dp[20000];
8 int n,k;
9 LL a[20000];
10 LL ABS(LL a)
11 {
12 if(a<0) return -a;
13 return a;
14 }
15 bool ok(LL c)
16 {
17 memset(dp,0,sizeof(dp));
18 for(int i=1; i<=n; i++)
19 {
20 dp[i]=i;
21 for(int j=1; j<i; j++)
22 {
23 if(ABS(a[i]-a[j])<=(LL)(i-j)*c)
24 dp[i]=min(dp[i],dp[j]+(i-j-1));
25 }
26 if(dp[i]+(n-i-1)<=k) return true;
27 }
28 return false;
29 }
30
31 int main()
32 {
33 while(scanf("%d%d",&n,&k)!=EOF)
34 {
35 for(int i=1; i<=n; i++)
36 {
37 scanf("%I64d",&a[i]);
38 }
39 LL l=0,r=inf;
40 while(l<=r)
41 {
42 LL mid=(l+r)/2;
43 if(ok(mid))
44 {
45 r=mid-1;
46 }
47 else l=mid+1;
48 }
49 printf("%I64d
",l);
50 }
51 return 0;
52 }
View Code