CSU 2249 Altruistic Amphibians DP

今天是这个学期第一场湖南多校训练赛,打的是真的自闭。

这个题是这场比赛的A题,想了n久,最后还是GG

题目链接:http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2249

题目大意,有n只青蛙想从一个深度为d的井中跳出去,因此青蛙需要叠罗汉。青蛙有3个属性,体重,身高,和跳跃力。叠罗汉唯一一个限制就是每只青蛙身上的青蛙的体重之和不能超过自身的体重。青蛙的跳跃力加上身下的青蛙的身高之和如果严格大于d,青蛙就能跳出去。
n<1e5, &lt; 1 e 8 d &lt; 1 e 8 \sum体重&lt;1e8,d&lt;1e8
看到这个题,数据范围这么大,完全不敢往dp想,虽然时限给了6s。直到有人说了是dp都觉得不可思议。
比赛的时候想到了总的叠起来的青蛙不会超过30只。。貌似没什么卵用。

正解是dp。

dp[i]表示的是能承重w的最大高度(注意这里是承重,不是下面青蛙的总重量)。
dp前需要将青蛙按体重从大到小排序,因为重的青蛙肯定不能在轻的青蛙上面。
因此转移方程就是dp[j]=max(dp[j],h[i]+dp[w[i]+j])(for j in range[1,wi-1])

完整代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int M=1e8+5;
int dp[M];
struct node{
    int w,l,h;
}p[N];
const bool cmp(node n1,node n2){
    return n1.w>n2.w;
}
int main(){
    int n,h;
    scanf("%d%d",&n,&h);
    for(int i=0;i<n;i++){
        scanf("%d%d%d",&p[i].l,&p[i].w,&p[i].h);
    }
    sort(p,p+n,cmp);
    int ans=0;
    for(int i=0;i<n;i++){
        if(dp[p[i].w]+p[i].l>h){
            ans++;
        }
        for(int j=1;j<p[i].w&&j+p[i].w<M;j++){
            dp[j]=max(dp[j],p[i].h+dp[j+p[i].w]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Monster_ixx/article/details/88386201