問題描述
雖然const_bh的遊戲造詣僅高於青銅六選手zbt,但是他的算法造詣也僅高於日常打鐵的吃瓜
羣衆zbt。但一日,const_bh偶有奇遇,遇到一位ACMdalao名曰Mengjiji,const_bh非常珍惜
這次機會,於是和Mengjiji一起搞了一場比(p)賽(y)。
比賽共有n道題,每道題有一個難度值,比賽要求題目必須按順序逐個去做,爲了減輕的蒟蒻
const_bh的壓力,Mengjiji把原來的題目序列分成了兩個序列,他和const_bh每人各負責
一個序列的題目,已知每個人將要面對的挑戰值爲他所負責的序列的相鄰兩個數的差的絕對值
一考const_bh,const_bh當然不會了,於是他偷偷的將這個問題用手機發給了聰明的你。
輸入描述
輸入包括兩行,第一行有一個n(n<=2000),代表題目的總數。
第二行有n個數,第i個數a[i]代表第i道題的難度值爲a[i]( 0< = a[i] < = 1000000000 ).
輸出描述
輸出僅一行,一個數字代表兩個人挑戰值和的最小值。
樣例輸入
5
1 2 1 3 4
樣例輸出
2
來源
第三屆山西省大學生程序設計大賽
提示
將 【1,2,1,3,4】分成【1,1】和【2,3,4】兩個序列,第一個序列的挑戰值爲0,第二個序列的挑戰值爲2.所以和爲2.
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
//4 20 8 5 1 9
int n;
long long f[2005][2005],a[2005],dp[2005][2005],mn=1e18;
int main()
{
freopen("1.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(n<=2){
cout<<0<<endl;return 0;
}
for(int i=1;i<=n;i++)
for(int j=0;j<i;j++)
{
if(j==0)
f[j][i]=0;
else
f[j][i]=abs(a[i]-a[j]);
}
// for(int i=1;i<=n;i++)for(int j=0;j<i;j++)cout<<f[j][i]<<endl;
memset(dp,0x3f3f3f3f,sizeof dp);
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
dp[0][i]=dp[0][i-1]+f[i-1][i];//write to f[i][i-1] that is error
}
// for(int i=1;i<=n;i++)
// {
// cout<<0<<","<<i<<","<<dp[0][i]<<" "<<endl;
// }
for(int i=2;i<=n;i++)//o(n^2)
for(int j=1;j<i;j++)
{
if(j==i-1)
{
for(int x=0;x<j;x++)
dp[j][i]=min(dp[j][i],dp[x][j]+f[x][i]);
}
else
{
dp[j][i]=dp[j][i-1]+f[i-1][i];
}
// cout<<j<<","<<i<<","<<dp[j][i]<<endl;
}
for(int i=1;i<=n;i++)
{
if(dp[i][n]<mn) mn=dp[i][n];
}
cout<<mn<<endl;
return 0;
}
/*
5
7 2 4 1 9
f[0][1]=0
f[0][2]=0
f[1][2]=5
f[0][3]=0
f[1][3]=3
f[2][3]=2
dp[1][2]=0
dp[1][3]=2 (7) (2,4)
dp[2][3]=3 (2) (7,4)
dp[1][4]=5 (7) (2,4,1)
dp[2][4]=6 (2) (7,4,1)
*/