CodeForces 13C Sequence :每次对数组中任一数+1或-1,最少需要多少次使数组成为不下降序列:dp

首先所有数最后所变成的数一定是原序列中有的数

然后可以将开辟一个新的数组为原数组,并排个序=

这样转移方程就比较好想了:dp[i][j]表示原序列中第i个数对应排序后的数组第j个数

1 if (i==1&&j==1) dp[i][j]=labs(a[i]-b[j]);
2 else if (i==1) dp[i][j]=min(dp[i][j-1],labs(a[i]-b[j]));
3 else if (j==1) dp[i][j]=dp[i-1][j]+labs(a[i]-b[j]);
4 else dp[i][j]=min(dp[i][j-1],dp[i-1][j]+labs(a[i]-b[j]));

这样是MLE的,继而可以用滚动数组将dp数组优化成一维=

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 long long a[5005],b[5005],dp[5005];
 7 int main()
 8 {
 9   long long n,i,j,ans;
10   scanf("%I64d",&n);
11   for (i=1;i<=n;i++)
12   {
13     scanf("%I64d",&a[i]);
14     b[i]=a[i];
15   }
16   memset(dp,0x3f,sizeof(dp));
17   sort(b+1,b+n+1);
18   for (i=1;i<=n;i++)
19     for (j=1;j<=n;j++)
20       if (i==1) dp[j]=min(dp[j-1],abs(a[1]-b[j]));
21       else if (j==1) dp[j]=dp[j]+abs(a[i]-b[j]);
22       else dp[j]=min(dp[j-1],dp[j]+abs(a[i]-b[j]));
23   ans=dp[1];
24   for (i=1;i<=n;i++)
25     ans=min(ans,dp[i]);
26   printf("%I64d\n",ans);
27   return 0;
28 }
View Code

题目链接:http://codeforces.com/problemset/problem/13/C

posted on 2015-03-25 19:17  xiao_xin  阅读(574)  评论(0编辑  收藏  举报

导航