zoukankan      html  css  js  c++  java
  • P2893 [USACO08FEB]修路Making the Grade

    题目地址


    易错点:

    • 由于数据太水,将序列变成单调不下降并计算最小花费即可.
    • 可以考虑枚举每一段路i和每一个高度j,则dp[i][j]=min(dp[i][j-1],dp[i-1][j]+cost)
    • 高度j范围太大,利用贪心的思想可以将所有可能的高度离散化.
    • 此时dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i]-b[j]).
    • 考虑到边界条件j=1,此时dp[i][j-1]=0,需要特殊处理.

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int MAXN=5010;
    int a[MAXN],b[MAXN],dp[MAXN][MAXN];
    int n;
    bool cmp1(int a,int b){
    	return a<b;
    }
    bool cmp2(int a,int b){
    	return a>b;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		b[i]=a[i];
    	}
    	int ans=2e9;
    	sort(b+1,b+n+1,cmp1);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(j==1)dp[i][j]=dp[i-1][j]+abs(a[i]-b[j]);
    			else dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i]-b[j]));
    		}
    	}
    	ans=min(ans,dp[n][n]);
    	sort(b+1,b+n+1,cmp2);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(j==1)dp[i][j]=dp[i-1][j]+abs(a[i]-b[j]);
    			else dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i]-b[j]));
    		}
    	}
    	printf("%d
    ",min(ans,dp[n][n]));
    	return 0;
    }
  • 相关阅读:
    取三级分销上下级用户id
    Map集合
    Log4j
    异常
    逻辑运算符
    变量
    变量名命名规则
    命名法
    Nessus
    Nmap扫描工具
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680600.html
Copyright © 2011-2022 走看看