标签:
题目大意:
给定一个序列,以最小代价将其变成单调不增或单调不减序列,求最小的变动价值;需要用到离散化dp
状态转移方程:
dp[i][j]=abs(j-w[i])+min(dp[i-1][k]);(k<=j)这里的k无需从1遍历到j。
只要在对j进行for循环的时候不断更新一个dp[i-1][j]的最小值mn=min(mn,dp[i-1][j]),
然后对dp[i][j]=abs(j-w[i])+mn即可;
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int N = 550; 8 const int MAX = 0x3fffffff; 9 long long dp[N][N]; 10 int a[N],b[N],n; 11 int cmp(int x,int y) 12 { 13 if(x>y) return 1; 14 return 0; 15 } 16 long long solve() 17 { 18 for(int i=1; i<=n; i++) 19 { 20 long long mn = dp[i-1][1]; 21 for(int k =1; k<=n; k++) 22 { 23 mn = min(mn,dp[i-1][k]); 24 dp[i][k] = abs(a[i]-b[k])+mn; 25 } 26 } 27 long long ans = dp[n][1]; 28 for(int i =1; i<=n; i++) 29 { 30 ans = min(ans,dp[n][i]); 31 } 32 return ans; 33 } 34 int main() 35 { 36 int T; 37 scanf("%d\n",&T);//poj这个地方不是T组数据,需要改动输入 38 while(T--) 39 { 40 scanf("%d",&n); 41 for(int i = 1; i<=n; i++) 42 { 43 scanf("%d",&a[i]); 44 b[i] = a[i]; 45 } 46 sort(b+1,b+n+1); 47 long long ans1 = solve();//一次递增序列 48 sort(b+1,b+1+n,cmp); 49 long long ans2 = solve();//一次递减序列求最小值 50 long long ans=min(ans1,ans2); 51 printf("%lld\n",ans); 52 } 53 return 0; 54 }
标签:
原文地址:http://www.cnblogs.com/lovychen/p/4425058.html