zoukankan      html  css  js  c++  java
  • 动规-POJ-3666

    http://poj.org/problem?id=3666

    Making the Grade

    给定一个正整数数列,要求通过对每一个元素加上或减去任意值,使得数列非严格递增(虽然题设要求还可以非严格递减,但是实际数据只要求非严格递增)。

    求所得数列与原数列各个对应元素差的绝对值之和的最小值。

    解题报告

    思路

    由于要求最终改变的绝对值和最小,所以可以知道所得解的数列中元素的最大值即原数列arr的最大值。

    以此类推,所得解的数列中,每个元素必然取自原数列arr。

    那么可将原数列进行排序,得到可取值数列num。

    若依次对数列的每个元素进行修改,那么修改第i个数的值后的总代价仅仅与修改至第i-1个数的总代价有关。

    而修改可取的值均来自num,则有状态转移方程:

    修改arr[i]为num[j]后的总代价为:dp[i][j] = abs(arr[i] - num[j]) + min( dp[i-1][0], d[[i-1][1], ... , dp[i-1][j] )

    代码

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 2003;
    
    int a[maxn], b[maxn];
    int num[maxn];
    int dp[maxn][maxn];
    int n;
    
    int Work(int *arr){
        int last = arr[0];
        int minNum;
        for(int i=1; i<=n; i++){
            dp[0][i] = 0;
        }
        for(int i=1; i<=n; i++){
            minNum = dp[i-1][1];
            for(int j = 1; j<=n ; j ++){
                minNum = min(dp[i-1][j], minNum);
                dp[i][j] = abs(arr[i] - num[j]) + minNum;
            }
        }
        int ans = dp[n][1];
        for(int i=1; i<=n; i++){
            ans = min(dp[n][i], ans);
        }
        return ans;
    }
    
    int main(){
    
        while(cin >> n){
            for(int i=1; i<=n; i++){
                cin >> a[i];
                num[i] = a[i];
                b[n-1-i] = a[i];
            }
            sort(num+1, num+n+1);
            cout << Work(a)<< endl;
        }
        return 0;
    }

    --(完)--

  • 相关阅读:
    rest-framework之路由
    rest-framework之频率控制
    mysql 模糊查询 concat()
    解决spring使用动态代理
    MySQL巧用sum,case...when...优化统计查询
    解决maven项目中有小红叉的问题
    google ---gson字符串数组用GSON解析然后用逗号隔开拼接,去掉最后一个逗号
    Elicpse使用技巧-打开选中文件文件夹或者包的当前目录
    powdesigner建表
    遍历map
  • 原文地址:https://www.cnblogs.com/Bcai0797/p/6991365.html
Copyright © 2011-2022 走看看