Codeforces13C. Sequence

题目

Solution

1.dp

变化后的每一个值肯定是等于原来序列的某个值(不会证)
(a为原序列,b为排序后的序列),方程的意思是,把序列前i个数变为非递减序列并且以不超过b[j]的值结尾的最小花费,那么它要么是以不超过b[j-1]结尾的最小花费,或者是刚好以b[j]结尾的最小花费

#include<bits/stdc++.h>
using namespace std;
int n,a[5003],i,j,b[5003],x,y=1;
long long f[2][5003];
int main(){
    cin>>n;
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    memcpy(b,a,sizeof(a));
    sort(b+1,b+n+1);
    for (i=1;i<=n;i++,x^=1,y^=1){
        memset(f[y],1,sizeof(f[y]));
        for (j=1;j<=n;j++) f[y][j]=min(f[y][j-1],f[x][j]+abs(a[i]-b[j]));
    }
    cout<<f[x][n];
}

2.贪心

用与Codeforces867E. Buy Low Sell High的方法,把大于小于号什么的改一下就好了(也不会证)

#include<bits/stdc++.h>
using namespace std;
int i,x,n;
long long ans;
priority_queue<int>q;
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(){
    int x=0,fl=1;char ch=gc();
    for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
    for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
    return x*fl;
}
int main(){
	n=rd();
	for (i=0;i<n;i++){
		x=rd();
		if (q.empty() || x>=q.top()) q.push(x);
		else ans+=q.top()-x,q.pop(),q.push(x),q.push(x);
	}
	printf("%lld",ans);
}

据说还有斜率的做法,如果找到了会加上

猜你喜欢

转载自blog.csdn.net/xumingyang0/article/details/85227046