CF360B Levko and Array(DP+二分答案)
阿新 • • 發佈:2020-09-11
題意:
一個長度為n的序列a[i],可以將其中k個數的值任意改變,要求最小化相鄰兩個數絕對值之差的最大值
題解:
/* *author: zlc *zucc_acm_lab *just do it */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const double pi=acos(-1.0); const double eps=1e-6; const int mod=1e9+7; const int inf=1e9; const int maxn=2e5+100; inline intread () {int x=0;int f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;} ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}int n,k; int a[2005]; int dp[2005]; //dp[i]表示前i個值中相鄰兩個數絕對值差不超過mid且第i個值不變,最少的改變次數 //只有當a[i]和a[j]的差不超過mid*(i-j)時才有可能通過改變i~j的元素使得合法 //最後存在某個數使得dp[i]+n-k<=k,說明mid值合法 int check (ll mid) { dp[1]=0; for (int i=2;i<=n;i++) { dp[i]=i-1; for (int j=1;j<i;j++) { if (abs(a[i]-a[j])<=(ll)mid*(i-j)) dp[i]=min(dp[i],dp[j]+i-j-1); } } if (dp[n]<=k) return 1; for (int i=1;i<=n;i++) if (dp[i]+n-i<=k) return 1; return 0; } int main () { ll ans=0; n=read(),k=read(); for (int i=1;i<=n;i++) a[i]=read(); ll l=0,r=2e9; while (l<=r) { ll mid=(l+r)>>1; if (check(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("%lld\n",ans); return 0; }