洛谷1156 垃圾陷阱 dp

https://www.luogu.org/problem/show?pid=1156
这个题状态有很多种表示方法:
1. f[i]表示堆到i的高度时最大生命值是多少。
堆 f[i+a[j]]=max( f[ i+a[j] ] , f[i] ) ;
吃 f[i]=f[i]+b[j];
2. bool f[ i ][ j ]表示能否到达 i 高度, j 血量。
然后时间复杂度是n×T×D,由于DP的常数非常小,所以1亿左右的数据是可以大胆跑的。

#include<bits/stdc++.h>
#define Max(x,y) x>y?x:y
using namespace std;
struct per{
    int t,f,h;
    void read()
    {scanf("%d%d%d",&t,&f,&h);}
}p[105];
bool cmp(per a,per b)
{return a.t<b.t;}
bool dp[1500][350];
int main()
{
    int d,g;
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;i++)
        p[i].read();
    sort(p+1,p+g+1,cmp);
    int n=p[g].t;
    int ans=10;
    for(int i=0;i<=10;i++)
        dp[i][0]=1;
    for(int i=1;i<=g;i++)
    for(int j=n;j>=0;j--)
    for(int k=d;k>=0;k--)
    {
        if(dp[j][k]&&j>=p[i].t)
        {
            dp[j][k+p[i].h]=1;
            if(k+p[i].h>=d)
            {
                ans=p[i].t;
                printf("%d",ans);
                return 0;
            }
            dp[j+p[i].f][k]=1;
        }
    }
    ans=10;
    for(int i=1;i<=g;i++)
    {
        if(ans>=p[i].t)
            ans+=p[i].f;
        else break;
    }
    printf("%d",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值