zoukankan      html  css  js  c++  java
  • ZOJ 3632 Watermelon Full of Water(dp+线段树 单点修改)

    题意:

           一共有n天

            每天西瓜售价为dp[i]元

            该天的西瓜能吃v[i]天 而且这天如果买了西瓜之前的西瓜就要扔掉

            问每天都吃到西瓜的最小花费是多少

    思路:

           从最后一天开始dp最小花费

           并用线段树单点更新来维护

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    #define ll long long
    #define INF 1e10
    ll dp[50000+100];//从后往前 dp[i]必买西瓜的最小花费
    int v[50000+100];
    ll sum[200000+100];
    int n;
    void push(int rt)
    {
        sum[rt]=min(sum[rt<<1],sum[rt<<1|1]);
    }
    void build(int l,int r,int rt)
    {
        sum[rt]=INF;
        if(l==r)
        {
           return ;
        }
        int m=(l+r)>>1;
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        push(rt);
    }
    void update(int key,ll add,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]=min(sum[rt],add);
            return ;
        }
        int m=(l+r)>>1;
        if(key<=m) update(key,add,l,m,rt<<1);
        else update(key,add,m+1,r,rt<<1|1);
        push(rt);
    }
    ll query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            return sum[rt];
        }
        ll res1=INF,res2=INF;
        int m=(l+r)>>1;
        if(L<=m)
        {
            res1=query(L,R,l,m,rt<<1);
        }
        if(R>m)
        {
            res2=query(L,R,m+1,r,rt<<1|1);
        }
        return min(res1,res2);
    }
    int main()
    {
        int i,j,k;
        while(scanf("%d",&n)!=EOF)
        {
            build(1,n+1,1);
            for(i=1;i<=n;i++)
            {
                scanf("%lld",&dp[i]);
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&v[i]);
            }
            dp[n+1]=0;
            update(n+1,dp[n+1],1,n+1,1);
            for(i=n;i>=1;i--)
            {
                int r=i+v[i];
                if(r>n+1) r=n+1;
                ll next=query(i+1,r,1,n+1,1);
                dp[i]+=next;
                update(i,dp[i],1,n+1,1);
            }
            
            printf("%lld
    ",dp[1]);
        }
        return 0;
    }
    
  • 相关阅读:
    del:根据索引值删除元素
    Python insert()方法插入元素
    Python extend()方法添加元素
    Python append()方法添加元素
    Python list列表添加元素的3种方法
    什么是序列,Python序列详解(包括序列类型和常用操作)
    Python运算符优先级和结合性一览表
    Python print()函数高级用法
    Python input()函数:获取用户输入的字符串
    Python变量的定义和使用
  • 原文地址:https://www.cnblogs.com/sola1994/p/4430152.html
Copyright © 2011-2022 走看看