Codeforces 13C(DP)

本文探讨了一个涉及数列操作以形成非降序列的问题,通过动态规划算法找到最少的操作次数。利用滚动数组优化空间复杂度,实现高效求解。

题意:给出一个数列长度小于5000,每次操作将数列中的数加1或减1,问最少需要多少步操作可以得到一个不降序列;

分析:可知最少的次数,一定是由原来的数据构成的(据说可以用反证法证),即有原来的数组成的不降子序列中有一个最小的情况;

  我们用F[i][j] = min(F[i][j -1] (不包含这一个时),F[i-1][j] + fabs(A[i] - B[j])(包含这一种时));其中B[]代表不重非减序列i,j代表前个数最大为B[j]时的最优情况;

注意:本题数据大,F[][]的过程用到了滚动数组;

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <math.h>
 5 int A[5001],B[5001],C[5001];
 6 __int64 F[3][5001];
 7 __int64 min(__int64 a,__int64 b)
 8 {
 9     return a > b ? b:a;
10 }
11 int cmp(const void *a,const void *b)
12 {
13     return *(int *)a - *(int *)b;
14 }
15 int main()
16 {
17     int n,m,i,j,a,b;
18     scanf("%d",&n);
19     for(i = 1;i <= n;i ++)
20     {
21         scanf("%d",&A[i]);
22         C[i] = A[i];
23     }
24     qsort(C + 1, n, sizeof(C[0]), cmp);
25     B[1] = C[1];
26     m = 1;
27     for(i = 2; i<= n;i ++)
28     if(C[i] > B[m])
29     {
30         ++ m;
31         B[m] = C[i];
32     }
33     F[1][1] = fabs(A[1] - B[1]);
34     for(i = 2;i <= m;i ++)
35         F[1][i] = min(F[1][i -1],fabs(A[1] - B[i]));
36     for(i = 2;i <= n;i ++)
37         {
38             F[i&1][1] = F[1 - (i&1)][1] + fabs(A[i] - B[1]);
39             for(j = 2;j <= m;j ++)
40         F[i&1][j] = min(F[i&1][j - 1],F[1 - i&1][j] + fabs(A[i] - B[j]));
41         }
42     printf("%I64d",F[n&1][m]);
43     return  0;
44 }
View Code

 

转载于:https://www.cnblogs.com/AHU-songyuan2235/p/3356182.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值