题目链接
大概题意
一条土路上有n段,每一段的高度可能各不相同。现在要把这条路修成单调递增或者单调递减的路,修路的花费是abs(i,j)i是修之前的高度,j是修之后的高度。问你修路的最小花费是多少
解题思路
刚开始的代码
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int min1=0x3f3f3f3f;
for(int k=1;k<=j;k++)
min1=min(min1,dp[i-1][k]);
dp[i][j]=min1+abs(a[i]-b[j]);
}
}
然后T掉了,我就想着优化,发现自己宛如一个智障,这么简单的优化竟然想不出来。。。i的这个状态是从i-1来的,所以最后一重是可以去掉的
之前做过好像是省赛的原题。。。但是省赛的数据比较水,三个循环就过了,这个要加优化
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[2005],b[2005];
int dp[2005][2005],n,dd[2005][2005];
int cmp(int x,int y)
{
return x>y;
}
int solve()
{
for(int i=1;i<=n;i++)
{
int min1=0x3f3f3f3f;
for(int j=1;j<=n;j++)
{
// for(int k=1;k<=j;k++)
// minn=min(minn,dp[i-1][k]);
min1=min(dp[i-1][j],min1);
dp[i][j]=min1+abs(a[i]-b[j]);
}
}
int ans=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
//printf("%d\n",dp[n][i]);
ans=min(ans,dp[n][i]);
}
return ans;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int ans1=solve();
sort(b+1,b+1+n,cmp);
int ans2=solve();
printf("%d\n",min(ans1,ans2));
}
return 0;
}