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 }