zoukankan      html  css  js  c++  java
  • Codeforces 940E

    940E - Cashback

    思路:

    dp+rmq

    可以证明最后划分的区间可以由长度为1和长度为c的区间组成的,这样就可以用O(n)的dp求了,区间最小值随便拿什么维护都可以

    状态:dp[i]表示到i这个位置为止的最小划分和

    初始状态:dp[0]=0

    目标状态:dp[n]

    状态转移:dp[i]=min(dp[i-1]+a[i],dp[i-c]+sum[i]-sum[i-c]+minmum(i-c+1,i))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define pli pair<ll,int>
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    const int INF=0x7f7f7f7f;
    int a[N],tree[N<<2],cnt;
    ll sum[N],dp[N];
    void push_up(int rt){
        tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
    }
    void build(int rt,int l,int r){
        if(l==r){
            cin>>a[++cnt];
            tree[rt]=a[cnt];
            return ;
        }
        int m=(l+r)>>1;
        build(ls);
        build(rs);
        push_up(rt);
    }
    int query(int L,int R,int rt,int l,int r){
        if(L<=l&&r<=R){
            return tree[rt];
        }
        int ans=INF,m=(l+r)>>1;
        if(L<=m)ans=min(ans,query(L,R,ls));
        if(R>m)ans=min(ans,query(L,R,rs));
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int n,c;
        cin>>n>>c;
        build(1,1,n);
        for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
        for(int i=1;i<=n;i++){
            if(i-c>=0)dp[i]=min(dp[i-1]+a[i],dp[i-c]+sum[i]-sum[i-c]-query(i-c+1,i,1,1,n));
            else dp[i]=dp[i-1]+a[i];
        }
        cout<<dp[n]<<endl;
        return 0;
    }
  • 相关阅读:
    大一励志的我,现在已经大三了
    Jenkins+K8s实现持续集成
    Jenkins搭建自动化测试环境
    软件开发式样书 6
    软件开发式样书 5
    软件开发式样书 4
    软件开发式样书 3
    软件开发式样书 2
    软件开发式样书 1
    Git学习笔记
  • 原文地址:https://www.cnblogs.com/widsom/p/8494892.html
Copyright © 2011-2022 走看看