zoukankan      html  css  js  c++  java
  • Educational DP Contest Q

    Q - Flowers

    原题链接:https://atcoder.jp/contests/dp/tasks/dp_q

    题目大意:

    n支花,第i支花的高为w[i],价值为v[i],其中每支花的高度都不相同,范围在1到n。求从给定的花的序列中找到一段高度递增的子序列,求这段子序列的价值最大值。

    解题思路:

    建立数组$dp,dp[i]$为取第i朵花时的最大价值,在求要第i支花时的最大值时,要找到他前边比他矮的花的价值最大值,然后$dp[i]=dp[j]+v[i]$,在找$dp[j]$时,不能遍历。因为高度在$1-n$这个范围里,所以可以建立一个树状数组来存储前i个花的价值,这样就可以在$logn$的时间内求出前i支花中高度在$1-(w[i]-1)$的价值的最大值。

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define debug(a) cout<<#a<<":"<<a<<endl;
     5 const ll INF=0x3f3f3f3f;
     6 const ll N=1e6+7;
     7 const ll mod=1e9+7;
     8 ll maxn,minn;
     9 ll T,n,m;
    10 ll dp[N];
    11 ll w[N];
    12 ll v[N];
    13 
    14 ll arr[N],ans[N]; //对应原数组和树状数组
    15 
    16 ll lowbit(ll x){
    17     return x&(-x);
    18 }
    19 
    20 void update(ll i,ll k){    //在i位置加上k
    21     while(i<=n){
    22         ans[i]=max(ans[i],k);
    23         i=i+lowbit(i);
    24     }
    25 }
    26 
    27 ll query(ll i){        //求arr[1 - i]的最大值
    28     ll res = 0;
    29     while(i>0){
    30         res=max(res,ans[i]);
    31         i =i-lowbit(i);
    32     }
    33     return res;
    34 }
    35 
    36 int main(){
    37     cin>>n;
    38     for(ll i=1;i<=n;i++){
    39         scanf("%lld",w+i);
    40     }
    41     for(ll i=1;i<=n;i++){
    42         scanf("%lld",v+i);
    43     }
    44     for(ll i=1;i<=n;i++){
    45         dp[i]=v[i]+query(w[i]);
    46         maxn=max(maxn,dp[i]);
    47         update(w[i],dp[i]);
    48     }
    49     cout<<maxn<<endl;
    50     return 0;
    51 }
     
  • 相关阅读:
    Thread--使用condition实现顺序执行
    Thread--condition
    Thread--lock,lockInterruptibly,tryLock,tryLock(long timeout, TimeUnit unit)
    Thread--线程间通信--管道
    Thread--生产者消费者假死分析
    Thread--生产者消费者
    Java--定时
    Thread--两线程交替打印
    重装系统都杀不掉的十大病毒
    常用工具
  • 原文地址:https://www.cnblogs.com/meanttobe/p/12852839.html
Copyright © 2011-2022 走看看