P2501 [HAOI2006] 数字序列
#include <bits/stdc++.h>
using namespace std;
const int N = 35 * 1000 + 10;
int n;
int f[N],a[N];
vector <int> pre[N];
int dp[N];
long long ans[N];
int len[N];
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;i++)
scanf("%d",&f[i]),a[i] = f[i] - i;
dp[0] = 0;
a[0] = -999999999;
dp[1] = 1;
pre[1].push_back(0);
for(int i = 2;i <= n;i++)
{
//cout << i << endl;
int maxans = 0,cnt = -1;
for(int j = 0;j < i;j++)
{
if(a[j] <= a[i])
{
if(dp[j] > maxans)
{
maxans = dp[j];
cnt = -1;
pre[i].clear();
pre[i].push_back(j);
}
else if(dp[j] == maxans)
{
pre[i].push_back(j);
}
}
}
dp[i] = maxans + 1;
len[i] = pre[i].size() - 1;//len不是个数
}
int ans1 = -1;
for(int i = 1;i <= n;i++)
ans1 = max(ans1,dp[i]);
printf("%d\n",n - ans1);
for(int i = 1;i <= n;i++)
{
if(pre[i][0] == 0 && len[i] == 0)
{
for(int j = 1;j < i;j++)
{
ans[i] += (a[j] - a[i]);
}
}
else
{
ans[i] = 1999999999;
for(int j = 0;j <= len[i];j++)
{
int t = pre[i][j];
long long temp = ans[t];
long long min_plus = 1999999999;
long long xh1 = 0,dh1 = 0;
int dn1 = 0,xn1 = 0;
int xn2 = 0,dn2 = 0;
long long xh2 = 0,dh2 = 0;
for(int g = t + 1;g < i;g++)
{
if(a[g] > a[i])dn2++,dh2 += a[g];
else xn2++,xh2 += a[g];
}
for(int k = t;k < i;k++)
{
long long tans = dh2 - a[i] * dn2 + xn2 * a[i] - xh2;
tans += dh1 - a[t] * dn1 + xn1 * a[t] - xh1;
min_plus = min(min_plus,tans);
if(a[k + 1] < a[t])
{
xn1 ++;
xh1 += a[k + 1];
}
else
{
dn1 ++;
dh1 += a[k + 1];
}
if(a[k + 1] < a[i])
{
xn2 --;
xh1 -= a[k + 1];
}
else
{
dn2 --;
dh1 -= a[k + 1];
}
}
temp += min_plus;
ans[i] = min(ans[i],temp);
}
}
}
long long minn = 1999999999;
for(int i = 1;i <= n;i++)
{
if(dp[i] == ans1)
{
long long tt = ans[i];
for(int j = i + 1;j <= n;j++)tt += a[i] - a[j];
minn = min(minn,tt);
}
}
printf("%lld\n",minn);
return 0;
}
熬不住了,先睡觉了,明天再写思路