https://www.bnuoj.com/v3/contest_show.php?cid=8095#problem/A
以为所以的dp[i]+n-i一定是dp[n]最小,但并不是
正确代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2000 + 100;
LL arr[N], dp[N];
int n,k;
bool check(LL mid)
{
for(int i=1;i<=n;i++)
{
dp[i] = i-1;
for(int j=1;j<i;j++)
{
if( abs(arr[i] - arr[j]) <= (i-j)*mid )
dp[i] = min(dp[i],dp[j] + (i-j-1));
}
// if(dp[i] + n-i <= k) return true;
}
// return false;
<span style="color:#ff0000;">//就是这个地方,卡了一万年</span>
for(int i=1;i<=n;i++)
if(dp[i]+n-i<=k)
return 1;
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
LL L = 0, R = 0;
for(int i=1;i<=n;i++)
{
scanf("%I64d",&arr[i]);
if(i!=1) R = max(R,abs(arr[i]-arr[i-1]));
}
while( L+1 <= R )
{
LL mid = (L + R) >> 1;
if( check(mid) ) R = mid;
else L = mid + 1;
}
printf("%I64d\n",R);
return 0;
}