-
时间:2016-03-28 17:23:08 星期一
-
题目编号:[2016-03-28][POJ][3666][]Making the Grade]
-
分析:dp[i][j]表示把改到第i个数,且把a[i]改成b[i]需要的最少代价,已知b[j]递增,dp[i][j]由dp[i - 1][k]递推过来,如果改成非增,那么就要求 a[j] <= a[k],所以dp[i][j] = min(dp[i - 1][k] + d) k < j;
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 2000 + 10;
int a[maxn],b[maxn],n;
int dp[maxn][maxn];
bool cmp(int x,int y){
return x > y;
}
int main(){
scanf("%d",&n);
for(int i = 0;i < n ; ++i){
scanf("%d",&a[i]);
}
memcpy(b,a,sizeof(int) * (n + 1));
sort(b,b + n);
memset(dp,0x7f,sizeof(dp));
for(int i = 0;i < n ; ++i){
dp[0][i] = abs(a[0] - b[i]);
}
for(int i = 1;i < n ; ++i){
int mindp = 0x7f7f7f7f;
for(int j = 0;j < n;++j){
mindp = min(dp[i-1][j],mindp);
dp[i][j] = min(dp[i][j] , mindp + abs(a[i] - b[j]));
}
}
int ans = 0x7f7f7f7f;
for(int i = 0;i < n ; ++i){
ans = min(dp[n - 1][i] ,ans);
}
sort(b,b + n,cmp);
memset(dp,0x7f,sizeof(dp));
for(int i = 0;i < n ; ++i){
dp[0][i] = abs(a[0] - b[i]);
}
for(int i = 1;i < n ; ++i){
int mindp = 0x7f7f7f7f;
for(int j = 0;j < n;++j){
mindp = min(dp[i-1][j],mindp);
dp[i][j] = min(dp[i][j] , mindp + abs(a[i] - b[j]));
}
}
for(int i = 0;i < n ; ++i){
ans = min(dp[n - 1][i] ,ans);
}
printf("%d\n",ans);
return 0;
}
时间: 2024-12-22 03:27:06