【DP】Gym101933A Altruistic Amphibians

S o u r c e : Source: Source:2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
P r o b l e m : Problem: Problem:坑里有一堆青蛙,青蛙有身高、跳跃高度、体重。青蛙可以叠罗汉,但是不可以撑起超过自己体重的重量。问有多少青蛙可以跳出去。体重总和<=1e8
I d e a : Idea: Idea:
先将青蛙按照体重从大到小排,dp[w]表示能够撑起重量w的最大高度,那么dp[wi]+li > d表示这个青蛙可以跳出去。
注意到体重总和的trick,考虑状态转移方程: d p [ m i n ( w − w i , w i − 1 ) ] = m a x ( d p [ m i n ( w − w i , w i − 1 ) ] , d p [ w ] + h i ) dp[min(w-wi, wi-1)] = max(dp[min(w-wi, wi-1)], dp[w]+hi) dp[min(wwi,wi1)]=max(dp[min(wwi,wi1)],dp[w]+hi)
考虑 w i &lt; w &lt; = 2 ∗ w i − 1 wi&lt;w&lt;=2*wi-1 wi<w<=2wi1时, d p [ w − w i ] = m a x ( d p [ w − w i ] , d p [ w ] + h i ) dp[w-wi] = max(dp[w-wi], dp[w]+hi) dp[wwi]=max(dp[wwi],dp[w]+hi)
w &gt; 2 ∗ w i − 1 w &gt; 2*wi-1 w>2wi1时, d p [ w i − 1 ] = ∑ m a x ( d p [ w ] + h i ) dp[wi-1] = \sum max(dp[w]+hi) dp[wi1]=max(dp[w]+hi),由于dp数组显然是递减的,所以不用更新。
C o d e : Code: Code:

#include<bits/stdc++.h>
using namespace std;

#define I inline
#define pb push_back
typedef long long LL;

const int N = 1e5+10, M = 1e8+10;

struct Frog {
    int l, w, h;
    void read() { scanf("%d%d%d", &l, &w, &h); }
    bool operator<(const Frog &A) const { return w > A.w; }
}a[N];

int dp[M];

I void work() {
    int n, D, ans = 0; scanf("%d%d", &n, &D);
    for(int i = 0; i < n; i++) a[i].read();
    sort(a, a+n);
    for(int i = 0; i < n; i++) {
        int w = a[i].w;
        if(dp[w]+a[i].l > D) ans++;
        for(int x = w+1; x < min(2*w, M); x++) {
            dp[x-w] = max(dp[x-w], dp[x]+a[i].h);
        }
    }
    printf("%d\n", ans);
}

int main() {
    work();
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值