[2016-03-28][POJ][3666][]Making the Grade]

  • 时间: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;

  1. #include <algorithm>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5. const int maxn = 2000 + 10;
  6. int a[maxn],b[maxn],n;
  7. int dp[maxn][maxn];
  8. bool cmp(int x,int y){
  9. return x > y;
  10. }
  11. int main(){
  12. scanf("%d",&n);
  13. for(int i = 0;i < n ; ++i){
  14. scanf("%d",&a[i]);
  15. }
  16. memcpy(b,a,sizeof(int) * (n + 1));
  17. sort(b,b + n);
  18. memset(dp,0x7f,sizeof(dp));
  19. for(int i = 0;i < n ; ++i){
  20. dp[0][i] = abs(a[0] - b[i]);
  21. }
  22. for(int i = 1;i < n ; ++i){
  23. int mindp = 0x7f7f7f7f;
  24. for(int j = 0;j < n;++j){
  25. mindp = min(dp[i-1][j],mindp);
  26. dp[i][j] = min(dp[i][j] , mindp + abs(a[i] - b[j]));
  27. }
  28. }
  29. int ans = 0x7f7f7f7f;
  30. for(int i = 0;i < n ; ++i){
  31. ans = min(dp[n - 1][i] ,ans);
  32. }
  33. sort(b,b + n,cmp);
  34. memset(dp,0x7f,sizeof(dp));
  35. for(int i = 0;i < n ; ++i){
  36. dp[0][i] = abs(a[0] - b[i]);
  37. }
  38. for(int i = 1;i < n ; ++i){
  39. int mindp = 0x7f7f7f7f;
  40. for(int j = 0;j < n;++j){
  41. mindp = min(dp[i-1][j],mindp);
  42. dp[i][j] = min(dp[i][j] , mindp + abs(a[i] - b[j]));
  43. }
  44. }
  45. for(int i = 0;i < n ; ++i){
  46. ans = min(dp[n - 1][i] ,ans);
  47. }
  48. printf("%d\n",ans);
  49. return 0;
  50. }

来自为知笔记(Wiz)

时间: 2024-12-22 03:27:06

[2016-03-28][POJ][3666][]Making the Grade]的相关文章

Poj 3666 Making the Grade (排序+dp)

题目链接: Poj 3666 Making the Grade 题目描述: 给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价? 解题思路: 对于修好的路径的每个位置的高度肯定都是以前存在的高度,修好路后不会出现以前没有出现过得高度 dp[i][j]代表位置i的地面高度为第j个高度,然后我们可以把以前的路修好后变成非递减路径,或者把以前的路径首尾颠倒,然后修成非递减路径.状态转移方程为:dp[i][j] = min(dp[i-1][k]) + a[i] -

POJ 3666 Making the Grade [DP]

题意: 给定一个序列,以最小代价将其变成单调不增或单调不减序列,这里的代价看题目公式. 思路: 很容易想到是DP. 1. 对前i个序列,构成的最优解其实就是与两个参数有关.一个是这个序列处理后的最大值mx,和这个序列处理的代价值cost. 显然最大值mx最小最好(这样第i+1个值可以不花代价直接接在其后面的可能性更大),cost最小也最好(题意要求),但是两者往往是鱼和熊掌. 用dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost. 所以状态转移方

poj 3666 Making the Grade &amp; zoj 3512 Financial Fraud 左偏树 or dp

//poj 3666 //分析:只是在2005年集训队论文黄源河提到的题目上略微有一点点变化 1 #include"iostream" 2 #include"cstdio" 3 using namespace std; 4 const int maxn = 2100; 5 int v[maxn],l[maxn],r[maxn],d[maxn]; //节点信息 6 int N; 7 int tot,root[maxn],num_now[maxn],num_del[ma

POJ 3666 Making the Grade(数列变成非降序/非升序数组的最小代价,dp)

传送门: http://poj.org/problem?id=3666 Making the Grade Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9468   Accepted: 4406 Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would lik

POJ - 3666 Making the Grade(dp+离散化)

Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up or down a single slope, but they are not fond of an alternating succession of hills and valleys. FJ

POJ 3666 Making the Grade

传送门:http://poj.org/problem?id=3666 解题思路: dp[i][j]:代表第i个数以j结尾所花的代价..那么dp[i][j]=fabs(a[i]-j)+min(dp[i-1][k])k<j; 实现代码: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cmath>

poj 3666 Making the Grade 【dp】

题目链接:http://poj.org/problem?id=3666 题意:使得一个序列变为递增或递减序列的最小代价.代价为题中给的公式. 解法:dp[i][j]表示前i个数,以num[j]为末尾的最小代价. 更新的时候枚举 j 转移状态: for (int i = 2; i <= n; i++) { int t = inf; for (int j = 1; j <= n; j++) { t = min(t,dp[i-1][j]); dp[i][j] = t + abs(a[i] - num

poj 3666 Making the Grade (动态规划)

Making the Grade Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4647   Accepted: 2202 Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more than FJ would like. His cows do not mind climbing up

POJ 3666 Making the Grade (DP)

题意:输入N, 然后输入N个数,求最小的改动这些数使之成非严格递增即可,要是非严格递减,反过来再求一下就可以了. 析:并不会做,知道是DP,但就是不会,菜....d[i][j]表示前 i 个数中,最大的是 j,那么转移方程为,d[i][j] = abs(j-w[i])+min(d[i-1][k]);(k<=j). 用滚动数组更加快捷,空间复杂度也低. 代码如下: #include <cstdio> #include <string> #include <cstdlib&