zoukankan      html  css  js  c++  java
  • CF360B Levko and Array(DP+二分答案)

    题意:

    一个长度为n的序列a[i],可以将其中k个数的值任意改变,要求最小化相邻两个数绝对值之差的最大值

    题解:

     /*
     *author: zlc
     *zucc_acm_lab
     *just do it
     */
    #include<bits/stdc++.h> 
    using namespace std;
    typedef long long ll;
    const double pi=acos(-1.0);
    const double eps=1e-6;
    const int mod=1e9+7;
    const int inf=1e9;
    const int maxn=2e5+100;
    inline int read () {int x=0;int f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
    ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    int n,k;
    int a[2005];
    int dp[2005];
    //dp[i]表示前i个值中相邻两个数绝对值差不超过mid且第i个值不变,最少的改变次数 
    //只有当a[i]和a[j]的差不超过mid*(i-j)时才有可能通过改变i~j的元素使得合法
    //最后存在某个数使得dp[i]+n-k<=k,说明mid值合法 
    int check (ll mid) {
        dp[1]=0;
        for (int i=2;i<=n;i++) {
            dp[i]=i-1;
            for (int j=1;j<i;j++) {
                if (abs(a[i]-a[j])<=(ll)mid*(i-j))
                    dp[i]=min(dp[i],dp[j]+i-j-1);
            }
        }
        if (dp[n]<=k) return 1;
        for (int i=1;i<=n;i++) if (dp[i]+n-i<=k) return 1;
        return 0;
    }
    int main () {
        ll ans=0;
        n=read(),k=read();
        for (int i=1;i<=n;i++) a[i]=read();
        ll l=0,r=2e9;
        while (l<=r) {
            ll mid=(l+r)>>1;
            if (check(mid)) {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    BZOJ2457 双端队列 题解
    POJ1723,1050,HDU4864题解(贪心)
    Splay与FHQ-Treap
    POJ3179 Corral the Cows题解
    使用easypoi根据表头信息动态导出excel
    Spring @Configuration注解
    vue脚手架vue-cli的搭建
    使用poi导出excel
    mybatis中的一对多和多对一
    angularjs模态框的使用
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13653286.html
Copyright © 2011-2022 走看看