Codeforces Round #371 (Div. 1) C. Sonya and Problem Wihtout a Legend(DP+思维)

题目链接
在这里插入图片描述
题意:给定一个初始数组,你每次操作可以选择数组中的一个数进行加1或者减1操作,问你最少要多少操作使得数组变成严格单调。
思路:感觉这个题思路完全想不到,我们将初始数组都执行a【i】=a【i】-i操作,然后我们思考一下这个修改成这样会有什么好处,修改后如果存在方案使得数组所有数都等于x(假设为x),那么我们最终答案的最小操作是不是就是等于a【i】变成x的步数累加起来?于是我们就可以枚举要变成那个数,最后取最小值就行了。
想得到的话倒是挺简单的,想不到的话就呵呵了QAQ

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e3+1;
ll dp[maxn][maxn],a[maxn],b[maxn];
map<ll,ll>p;
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]),a[i]-=i,b[i]=a[i];
	sort(b+1,b+1+n);
	for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) dp[i][j]=1e18;
	for(int i=1;i<=n;++i)
	{
		ll minn=1e18;
		for(int j=1;j<=n;++j)
		{
			minn=min(minn,dp[i-1][j]);
			dp[i][j]=minn+abs(a[i]-b[j]);
		}
	}
	ll ans=1e18;
	for(int i=1;i<=n;++i) ans=min(ans,dp[n][i]);//最后看一下变成那个数花费最小
	printf("%lld\n",ans);
}
发布了328 篇原创文章 · 获赞 1 · 访问量 9092

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/105229874