1. 程式人生 > >CF 713C Sonya and Problem Wihtout a Legend(DP)

CF 713C Sonya and Problem Wihtout a Legend(DP)

can 一個數 ica BE 大於 req arr sts ger

原版題意:給定一個序列,每次操作給其中一個數$+1$或$-1$,問最少需要多少操作使得整個序列為不下降序列。

題解:不下降序列最後修改完成後的各個數一定是原序列中的某一個數。關於這個的理解看到網上的一個解釋:原序列,從左到右掃過去,如果左邊的大於右邊的,要麽左邊的減掉使其等於右邊的,要麽右邊的加上使其等於左邊的。

$dp[i][j]$:前i個數以原序列排序後的第j個數為結尾需要的最少操作。

狀態轉移方程:$dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i]-b[j]))$。當前 $i j$ 狀態要麽從末尾為第j-1個數轉移過來,要麽從前i-1個數+第i個數與末尾為第j個數的差值轉移過來。

題目鏈接:http://codeforces.com/problemset/problem/713/C

題目:

Sonya was unable to think of a story for this problem, so here comes the formal description.

You are given the array containing n positive integers. At one turn you can pick any element and increase or decrease it by 1. The goal is the make the array strictly increasing by making the minimum possible number of operations. You are allowed to change elements in any way, they can become negative or equal to 0.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 3000) — the length of the array.

Next line contains n integer ai (1 ≤ ai ≤ 109).

Output

Print the minimum number of operation required to make the array strictly increasing.

Examples input Copy
7
2 1 5 11 5 9 11
output
9
input Copy
5
5 4 3 2 1
output
12
Note

In the first sample, the array is going to look as follows:

2 3 5 6 7 9 11

|2 - 2| + |1 - 3| + |5 - 5| + |11 - 6| + |5 - 7| + |9 - 9| + |11 - 11| = 9

And for the second sample:

1 2 3 4 5

|5 - 1| + |4 - 2| + |3 - 3| + |2 - 4| + |1 - 5| = 12

題解:CF上這道題要求的不是不下降序列,而是嚴格單調遞增序列。

經過推導:$a_i < a_{i+1}$ —> $a_i <= a_{i+1} - 1$ —> $a_i - i <= a_{i+1} - (i+1)$,我們把每一項都減去i,就轉換成原版了。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 typedef long long LL;
 6 const int N=3333;
 7 LL a[N],b[N],dp[N][N];
 8 
 9 int main(){
10     int n;
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++){
13         scanf("%lld",&a[i]);
14         a[i]-=i;
15         b[i]=a[i];
16         for(int j=0;j<=n;j++) dp[i][j]=1e18;
17     }
18     sort(b+1,b+1+n);
19     for(int i=1;i<=n;i++)
20     for(int j=1;j<=n;j++)
21     dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i]-b[j]));
22 
23     printf("%lld\n",dp[n][n]);
24     return 0;
25 }

CF 713C Sonya and Problem Wihtout a Legend(DP)