poj3666+codeforces713C

来源:互联网 发布:知乎 约翰事件 编辑:程序博客网 时间:2024/06/10 15:52

poj3666

题意:给出一个序列a,用最小的花费将序列变为非严格递增序列b。修改一个数的花费为该数修改前后差值的绝对值。abs(b[i]-a[i])

思路:

为使花费最小,修改后序列的每个值b[i]必为原序列a中的数。

dp[i][j]表示前i个数满足非严格递增,a[i]=b[j]情况下花费最小值。

转移方程dp[i][j]=min(dp[i-1][k])+abs(a[i]-b[j]; (k<=j)

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=2005;int a[maxn],b[maxn],dp[maxn][maxn];int main() {    int n,tmp,ans=1e9;    scanf("%d",&n);    for(int i=1;i<=n;++i) {        scanf("%d",&a[i]);        b[i]=a[i];    }    sort(b+1,b+n+1);    memset(dp,0,sizeof dp);    for(int i=1;i<=n;++i) dp[1][i]=abs(a[1]-b[i]);    for(int i=2;i<=n;++i) {        tmp=dp[i-1][1];        for(int j=1;j<=n;++j) {            tmp=min(tmp,dp[i-1][j]);            dp[i][j]=tmp+abs(a[i]-b[j]);        }    }    for(int i=1;i<=n;++i) ans=min(ans,dp[n][i]);    printf("%d\n",ans);    return 0;}



codeforces713C
题意:上题变形,序列修改为严格递增序列。
tip:a[i]=a[i]-i;

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=3005;ll a[maxn],b[maxn],dp[maxn][maxn];int main() {    int n;    ll tmp,ans=1e15;    scanf("%d",&n);    for(int i=1;i<=n;++i) {        scanf("%d",&a[i]);        a[i]=a[i]-i;        b[i]=a[i];    }    sort(b+1,b+1+n);    for(int i=1;i<=n;++i) dp[1][i]=abs(a[1]-b[i]);    for(int i=2;i<=n;++i) {        tmp=dp[i-1][1];        for(int j=1;j<=n;++j) {            tmp=min(dp[i-1][j],tmp);            dp[i][j]=tmp+abs(a[i]-b[j]);        }    }    for(int i=1;i<=n;++i) ans=min(ans,dp[n][i]);    printf("%I64d\n",ans);    return 0;}





0 0
原创粉丝点击